summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--Makefile2
-rw-r--r--cgit.c8
-rw-r--r--cgit.h1
-rw-r--r--cgitrc.5.txt6
m---------git0
-rw-r--r--html.c9
-rw-r--r--scan-tree.c8
-rw-r--r--shared.c2
-rwxr-xr-xtests/t0108-patch.sh2
-rw-r--r--ui-snapshot.c1
-rw-r--r--ui-summary.c42
11 files changed, 52 insertions, 29 deletions
diff --git a/Makefile b/Makefile
index 2a15469..23fdd53 100644
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,16 @@
1CGIT_VERSION = v0.8.3.3 1CGIT_VERSION = v0.8.3.3
2CGIT_SCRIPT_NAME = cgit.cgi 2CGIT_SCRIPT_NAME = cgit.cgi
3CGIT_SCRIPT_PATH = /var/www/htdocs/cgit 3CGIT_SCRIPT_PATH = /var/www/htdocs/cgit
4CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH) 4CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH)
5CGIT_CONFIG = /etc/cgitrc 5CGIT_CONFIG = /etc/cgitrc
6CACHE_ROOT = /var/cache/cgit 6CACHE_ROOT = /var/cache/cgit
7SHA1_HEADER = <openssl/sha.h> 7SHA1_HEADER = <openssl/sha.h>
8GIT_VER = 1.7.2.2 8GIT_VER = 1.7.3
9GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2 9GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2
10INSTALL = install 10INSTALL = install
11 11
12# Define NO_STRCASESTR if you don't have strcasestr. 12# Define NO_STRCASESTR if you don't have strcasestr.
13# 13#
14# Define NO_OPENSSL to disable linking with OpenSSL and use bundled SHA1 14# Define NO_OPENSSL to disable linking with OpenSSL and use bundled SHA1
15# implementation (slower). 15# implementation (slower).
16# 16#
diff --git a/cgit.c b/cgit.c
index 5666875..e1d2216 100644
--- a/cgit.c
+++ b/cgit.c
@@ -67,21 +67,17 @@ void repo_config(struct cgit_repo *repo, const char *name, const char *value)
67 repo->enable_subject_links = atoi(value); 67 repo->enable_subject_links = atoi(value);
68 else if (!strcmp(name, "max-stats")) 68 else if (!strcmp(name, "max-stats"))
69 repo->max_stats = cgit_find_stats_period(value, NULL); 69 repo->max_stats = cgit_find_stats_period(value, NULL);
70 else if (!strcmp(name, "module-link")) 70 else if (!strcmp(name, "module-link"))
71 repo->module_link= xstrdup(value); 71 repo->module_link= xstrdup(value);
72 else if (!strcmp(name, "section")) 72 else if (!strcmp(name, "section"))
73 repo->section = xstrdup(value); 73 repo->section = xstrdup(value);
74 else if (!strcmp(name, "readme") && value != NULL) { 74 else if (!strcmp(name, "readme") && value != NULL) {
75 char *colon; 75 repo->readme = xstrdup(value);
76 if (*value == '/' || ((colon = strchr(value, ':')) != NULL && colon != value && *(colon + 1) != '\0'))
77 repo->readme = xstrdup(value);
78 else
79 repo->readme = xstrdup(fmt("%s/%s", repo->path, value));
80 } else if (ctx.cfg.enable_filter_overrides) { 76 } else if (ctx.cfg.enable_filter_overrides) {
81 if (!strcmp(name, "about-filter")) 77 if (!strcmp(name, "about-filter"))
82 repo->about_filter = new_filter(value, 0); 78 repo->about_filter = new_filter(value, 0);
83 else if (!strcmp(name, "commit-filter")) 79 else if (!strcmp(name, "commit-filter"))
84 repo->commit_filter = new_filter(value, 0); 80 repo->commit_filter = new_filter(value, 0);
85 else if (!strcmp(name, "source-filter")) 81 else if (!strcmp(name, "source-filter"))
86 repo->source_filter = new_filter(value, 1); 82 repo->source_filter = new_filter(value, 1);
87 } 83 }
@@ -92,16 +88,18 @@ void config_cb(const char *name, const char *value)
92 if (!strcmp(name, "section") || !strcmp(name, "repo.group")) 88 if (!strcmp(name, "section") || !strcmp(name, "repo.group"))
93 ctx.cfg.section = xstrdup(value); 89 ctx.cfg.section = xstrdup(value);
94 else if (!strcmp(name, "repo.url")) 90 else if (!strcmp(name, "repo.url"))
95 ctx.repo = cgit_add_repo(value); 91 ctx.repo = cgit_add_repo(value);
96 else if (ctx.repo && !strcmp(name, "repo.path")) 92 else if (ctx.repo && !strcmp(name, "repo.path"))
97 ctx.repo->path = trim_end(value, '/'); 93 ctx.repo->path = trim_end(value, '/');
98 else if (ctx.repo && !prefixcmp(name, "repo.")) 94 else if (ctx.repo && !prefixcmp(name, "repo."))
99 repo_config(ctx.repo, name + 5, value); 95 repo_config(ctx.repo, name + 5, value);
96 else if (!strcmp(name, "readme"))
97 ctx.cfg.readme = xstrdup(value);
100 else if (!strcmp(name, "root-title")) 98 else if (!strcmp(name, "root-title"))
101 ctx.cfg.root_title = xstrdup(value); 99 ctx.cfg.root_title = xstrdup(value);
102 else if (!strcmp(name, "root-desc")) 100 else if (!strcmp(name, "root-desc"))
103 ctx.cfg.root_desc = xstrdup(value); 101 ctx.cfg.root_desc = xstrdup(value);
104 else if (!strcmp(name, "root-readme")) 102 else if (!strcmp(name, "root-readme"))
105 ctx.cfg.root_readme = xstrdup(value); 103 ctx.cfg.root_readme = xstrdup(value);
106 else if (!strcmp(name, "css")) 104 else if (!strcmp(name, "css"))
107 ctx.cfg.css = xstrdup(value); 105 ctx.cfg.css = xstrdup(value);
diff --git a/cgit.h b/cgit.h
index 9b269cc..f8076c5 100644
--- a/cgit.h
+++ b/cgit.h
@@ -163,16 +163,17 @@ struct cgit_config {
163 char *head_include; 163 char *head_include;
164 char *header; 164 char *header;
165 char *index_header; 165 char *index_header;
166 char *index_info; 166 char *index_info;
167 char *logo; 167 char *logo;
168 char *logo_link; 168 char *logo_link;
169 char *module_link; 169 char *module_link;
170 char *project_list; 170 char *project_list;
171 char *readme;
171 char *robots; 172 char *robots;
172 char *root_title; 173 char *root_title;
173 char *root_desc; 174 char *root_desc;
174 char *root_readme; 175 char *root_readme;
175 char *script_name; 176 char *script_name;
176 char *section; 177 char *section;
177 char *virtual_root; 178 char *virtual_root;
178 int cache_size; 179 int cache_size;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 95782df..ce78d41 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -229,16 +229,20 @@ noheader::
229 Flag which, when set to "1", will make cgit omit the standard header 229 Flag which, when set to "1", will make cgit omit the standard header
230 on all pages. Default value: none. See also: "embedded". 230 on all pages. Default value: none. See also: "embedded".
231 231
232project-list:: 232project-list::
233 A list of subdirectories inside of scan-path, relative to it, that 233 A list of subdirectories inside of scan-path, relative to it, that
234 should loaded as git repositories. This must be defined prior to 234 should loaded as git repositories. This must be defined prior to
235 scan-path. Default value: none. See also: scan-path. 235 scan-path. Default value: none. See also: scan-path.
236 236
237readme::
238 Text which will be used as default value for "repo.readme". Default
239 value: none.
240
237remove-suffix:: 241remove-suffix::
238 If set to "1" and scan-path is enabled, if any repositories are found 242 If set to "1" and scan-path is enabled, if any repositories are found
239 with a suffix of ".git", this suffix will be removed for the url and 243 with a suffix of ".git", this suffix will be removed for the url and
240 name. Default value: "0". See also: scan-path. 244 name. Default value: "0". See also: scan-path.
241 245
242renamelimit:: 246renamelimit::
243 Maximum number of files to consider when detecting renames. The value 247 Maximum number of files to consider when detecting renames. The value
244 "-1" uses the compiletime value in git (for further info, look at 248 "-1" uses the compiletime value in git (for further info, look at
@@ -374,17 +378,17 @@ repo.owner::
374repo.path:: 378repo.path::
375 An absolute path to the repository directory. For non-bare repositories 379 An absolute path to the repository directory. For non-bare repositories
376 this is the .git-directory. Default value: none. 380 this is the .git-directory. Default value: none.
377 381
378repo.readme:: 382repo.readme::
379 A path (relative to <repo.path>) which specifies a file to include 383 A path (relative to <repo.path>) which specifies a file to include
380 verbatim as the "About" page for this repo. You may also specify a 384 verbatim as the "About" page for this repo. You may also specify a
381 git refspec by head or by hash by prepending the refspec followed by 385 git refspec by head or by hash by prepending the refspec followed by
382 a colon. For example, "master:docs/readme.mkd" Default value: none. 386 a colon. For example, "master:docs/readme.mkd" Default value: <readme>.
383 387
384repo.snapshots:: 388repo.snapshots::
385 A mask of allowed snapshot-formats for this repo, restricted by the 389 A mask of allowed snapshot-formats for this repo, restricted by the
386 "snapshots" global setting. Default value: <snapshots>. 390 "snapshots" global setting. Default value: <snapshots>.
387 391
388repo.section:: 392repo.section::
389 Override the current section name for this repository. Default value: 393 Override the current section name for this repository. Default value:
390 none. 394 none.
diff --git a/git b/git
Subproject 8c67c392e1620fc3b749aa9e0b8da13bd84226f Subproject 87b50542a08ac6caa083ddc376e674424e37940
diff --git a/html.c b/html.c
index 337baeb..eaabf72 100644
--- a/html.c
+++ b/html.c
@@ -263,29 +263,30 @@ int hextoint(char c)
263 else if (c >= '0' && c <= '9') 263 else if (c >= '0' && c <= '9')
264 return c - '0'; 264 return c - '0';
265 else 265 else
266 return -1; 266 return -1;
267} 267}
268 268
269char *convert_query_hexchar(char *txt) 269char *convert_query_hexchar(char *txt)
270{ 270{
271 int d1, d2; 271 int d1, d2, n;
272 if (strlen(txt) < 3) { 272 n = strlen(txt);
273 if (n < 3) {
273 *txt = '\0'; 274 *txt = '\0';
274 return txt-1; 275 return txt-1;
275 } 276 }
276 d1 = hextoint(*(txt+1)); 277 d1 = hextoint(*(txt+1));
277 d2 = hextoint(*(txt+2)); 278 d2 = hextoint(*(txt+2));
278 if (d1<0 || d2<0) { 279 if (d1<0 || d2<0) {
279 strcpy(txt, txt+3); 280 memmove(txt, txt+3, n-3);
280 return txt-1; 281 return txt-1;
281 } else { 282 } else {
282 *txt = d1 * 16 + d2; 283 *txt = d1 * 16 + d2;
283 strcpy(txt+1, txt+3); 284 memmove(txt+1, txt+3, n-2);
284 return txt; 285 return txt;
285 } 286 }
286} 287}
287 288
288int http_parse_querystring(const char *txt_, void (*fn)(const char *name, const char *value)) 289int http_parse_querystring(const char *txt_, void (*fn)(const char *name, const char *value))
289{ 290{
290 char *t, *txt, *value = NULL, c; 291 char *t, *txt, *value = NULL, c;
291 292
diff --git a/scan-tree.c b/scan-tree.c
index 6ba9193..b5b50f3 100644
--- a/scan-tree.c
+++ b/scan-tree.c
@@ -113,19 +113,21 @@ static void add_repo(const char *base, const char *path, repo_config_fn fn)
113 owner = xstrdup(pwd->pw_gecos ? pwd->pw_gecos : pwd->pw_name); 113 owner = xstrdup(pwd->pw_gecos ? pwd->pw_gecos : pwd->pw_name);
114 } 114 }
115 repo->owner = owner; 115 repo->owner = owner;
116 116
117 p = fmt("%s/description", path); 117 p = fmt("%s/description", path);
118 if (!stat(p, &st)) 118 if (!stat(p, &st))
119 readfile(p, &repo->desc, &size); 119 readfile(p, &repo->desc, &size);
120 120
121 p = fmt("%s/README.html", path); 121 if (!repo->readme) {
122 if (!stat(p, &st)) 122 p = fmt("%s/README.html", path);
123 repo->readme = "README.html"; 123 if (!stat(p, &st))
124 repo->readme = "README.html";
125 }
124 if (ctx.cfg.section_from_path) { 126 if (ctx.cfg.section_from_path) {
125 n = ctx.cfg.section_from_path; 127 n = ctx.cfg.section_from_path;
126 if (n > 0) { 128 if (n > 0) {
127 slash = rel; 129 slash = rel;
128 while (slash && n && (slash = strchr(slash, '/'))) 130 while (slash && n && (slash = strchr(slash, '/')))
129 n--; 131 n--;
130 } else { 132 } else {
131 slash = rel + strlen(rel); 133 slash = rel + strlen(rel);
diff --git a/shared.c b/shared.c
index b42c2a2..72ac140 100644
--- a/shared.c
+++ b/shared.c
@@ -57,17 +57,17 @@ struct cgit_repo *cgit_add_repo(const char *url)
57 ret->defbranch = "master"; 57 ret->defbranch = "master";
58 ret->snapshots = ctx.cfg.snapshots; 58 ret->snapshots = ctx.cfg.snapshots;
59 ret->enable_log_filecount = ctx.cfg.enable_log_filecount; 59 ret->enable_log_filecount = ctx.cfg.enable_log_filecount;
60 ret->enable_log_linecount = ctx.cfg.enable_log_linecount; 60 ret->enable_log_linecount = ctx.cfg.enable_log_linecount;
61 ret->enable_remote_branches = ctx.cfg.enable_remote_branches; 61 ret->enable_remote_branches = ctx.cfg.enable_remote_branches;
62 ret->enable_subject_links = ctx.cfg.enable_subject_links; 62 ret->enable_subject_links = ctx.cfg.enable_subject_links;
63 ret->max_stats = ctx.cfg.max_stats; 63 ret->max_stats = ctx.cfg.max_stats;
64 ret->module_link = ctx.cfg.module_link; 64 ret->module_link = ctx.cfg.module_link;
65 ret->readme = NULL; 65 ret->readme = ctx.cfg.readme;
66 ret->mtime = -1; 66 ret->mtime = -1;
67 ret->about_filter = ctx.cfg.about_filter; 67 ret->about_filter = ctx.cfg.about_filter;
68 ret->commit_filter = ctx.cfg.commit_filter; 68 ret->commit_filter = ctx.cfg.commit_filter;
69 ret->source_filter = ctx.cfg.source_filter; 69 ret->source_filter = ctx.cfg.source_filter;
70 return ret; 70 return ret;
71} 71}
72 72
73struct cgit_repo *cgit_get_repoinfo(const char *url) 73struct cgit_repo *cgit_get_repoinfo(const char *url)
diff --git a/tests/t0108-patch.sh b/tests/t0108-patch.sh
index 33351d6..e608104 100755
--- a/tests/t0108-patch.sh
+++ b/tests/t0108-patch.sh
@@ -30,8 +30,10 @@ run_test 'find initial commit' '
30 30
31run_test 'generate patch for initial commit' ' 31run_test 'generate patch for initial commit' '
32 cgit_query "url=foo/patch&id=$root" >trash/tmp 32 cgit_query "url=foo/patch&id=$root" >trash/tmp
33' 33'
34 34
35run_test 'find `cgit` signature' ' 35run_test 'find `cgit` signature' '
36 tail -1 trash/tmp | grep -e "^cgit" 36 tail -1 trash/tmp | grep -e "^cgit"
37' 37'
38
39tests_done
diff --git a/ui-snapshot.c b/ui-snapshot.c
index 1b25dca..6e3412c 100644
--- a/ui-snapshot.c
+++ b/ui-snapshot.c
@@ -87,16 +87,17 @@ static int make_snapshot(const struct cgit_snapshot_format *format,
87 args.base = fmt("%s/", prefix); 87 args.base = fmt("%s/", prefix);
88 args.baselen = strlen(prefix) + 1; 88 args.baselen = strlen(prefix) + 1;
89 } else { 89 } else {
90 args.base = ""; 90 args.base = "";
91 args.baselen = 0; 91 args.baselen = 0;
92 } 92 }
93 args.tree = commit->tree; 93 args.tree = commit->tree;
94 args.time = commit->date; 94 args.time = commit->date;
95 args.compression_level = Z_DEFAULT_COMPRESSION;
95 ctx.page.mimetype = xstrdup(format->mimetype); 96 ctx.page.mimetype = xstrdup(format->mimetype);
96 ctx.page.filename = xstrdup(filename); 97 ctx.page.filename = xstrdup(filename);
97 cgit_print_http_headers(&ctx); 98 cgit_print_http_headers(&ctx);
98 format->write_func(&args); 99 format->write_func(&args);
99 return 0; 100 return 0;
100} 101}
101 102
102/* Try to guess the requested revision from the requested snapshot name. 103/* Try to guess the requested revision from the requested snapshot name.
diff --git a/ui-summary.c b/ui-summary.c
index 02f191e..b203bcc 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -65,43 +65,57 @@ void cgit_print_summary()
65 print_urls(ctx.repo->clone_url, NULL); 65 print_urls(ctx.repo->clone_url, NULL);
66 else if (ctx.cfg.clone_prefix) 66 else if (ctx.cfg.clone_prefix)
67 print_urls(ctx.cfg.clone_prefix, ctx.repo->url); 67 print_urls(ctx.cfg.clone_prefix, ctx.repo->url);
68 html("</table>"); 68 html("</table>");
69} 69}
70 70
71void cgit_print_repo_readme(char *path) 71void cgit_print_repo_readme(char *path)
72{ 72{
73 char *slash, *tmp, *colon, *ref = 0; 73 char *slash, *tmp, *colon, *ref;
74 74
75 if (!ctx.repo->readme) 75 if (!ctx.repo->readme || !(*ctx.repo->readme))
76 return; 76 return;
77 77
78 ref = NULL;
79
80 /* Check if the readme is tracked in the git repo. */
81 colon = strchr(ctx.repo->readme, ':');
82 if (colon && strlen(colon) > 1) {
83 *colon = '\0';
84 ref = ctx.repo->readme;
85 ctx.repo->readme = colon + 1;
86 if (!(*ctx.repo->readme))
87 return;
88 }
89
90 /* Prepend repo path to relative readme path unless tracked. */
91 if (!ref && *ctx.repo->readme != '/')
92 ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path,
93 ctx.repo->readme));
94
95 /* If a subpath is specified for the about page, make it relative
96 * to the directory containing the configured readme.
97 */
78 if (path) { 98 if (path) {
79 slash = strrchr(ctx.repo->readme, '/'); 99 slash = strrchr(ctx.repo->readme, '/');
80 if (!slash) { 100 if (!slash) {
81 slash = strchr(ctx.repo->readme, ':'); 101 if (!colon)
82 if (!slash)
83 return; 102 return;
103 slash = colon;
84 } 104 }
85 tmp = xmalloc(slash - ctx.repo->readme + 1 + strlen(path) + 1); 105 tmp = xmalloc(slash - ctx.repo->readme + 1 + strlen(path) + 1);
86 strncpy(tmp, ctx.repo->readme, slash - ctx.repo->readme + 1); 106 strncpy(tmp, ctx.repo->readme, slash - ctx.repo->readme + 1);
87 strcpy(tmp + (slash - ctx.repo->readme + 1), path); 107 strcpy(tmp + (slash - ctx.repo->readme + 1), path);
88 } else 108 } else
89 tmp = ctx.repo->readme; 109 tmp = ctx.repo->readme;
90 colon = strchr(tmp, ':'); 110
91 if (colon && strlen(colon) > 1) { 111 /* Print the calculated readme, either from the git repo or from the
92 *colon = '\0'; 112 * filesystem, while applying the about-filter.
93 ref = tmp; 113 */
94 tmp = colon + 1;
95 while ((*tmp == '/' || *tmp == ':') && *tmp != '\0')
96 ++tmp;
97 if (!(*tmp))
98 return;
99 }
100 html("<div id='summary'>"); 114 html("<div id='summary'>");
101 if (ctx.repo->about_filter) 115 if (ctx.repo->about_filter)
102 cgit_open_filter(ctx.repo->about_filter); 116 cgit_open_filter(ctx.repo->about_filter);
103 if (ref) 117 if (ref)
104 cgit_print_file(tmp, ref); 118 cgit_print_file(tmp, ref);
105 else 119 else
106 html_include(tmp); 120 html_include(tmp);
107 if (ctx.repo->about_filter) 121 if (ctx.repo->about_filter)