aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cgit.c23
-rw-r--r--cgit.h1
-rw-r--r--cgitrc.5.txt13
-rw-r--r--cmd.c42
-rw-r--r--cmd.h3
-rw-r--r--html.c15
-rw-r--r--parsing.c29
-rw-r--r--scan-tree.c1
-rw-r--r--shared.c19
-rwxr-xr-xtests/setup.sh25
-rwxr-xr-xtests/t0101-index.sh1
-rwxr-xr-xtests/t0103-log.sh10
-rw-r--r--ui-diff.c8
-rw-r--r--ui-log.c29
-rw-r--r--ui-repolist.c2
-rw-r--r--ui-tree.c2
16 files changed, 142 insertions, 81 deletions
diff --git a/cgit.c b/cgit.c
index 5d6e488..6be3754 100644
--- a/cgit.c
+++ b/cgit.c
@@ -29,6 +29,7 @@ void add_mimetype(const char *name, const char *value)
29struct cgit_filter *new_filter(const char *cmd, filter_type filtertype) 29struct cgit_filter *new_filter(const char *cmd, filter_type filtertype)
30{ 30{
31 struct cgit_filter *f; 31 struct cgit_filter *f;
32 int args_size = 0;
32 int extra_args; 33 int extra_args;
33 34
34 if (!cmd || !cmd[0]) 35 if (!cmd || !cmd[0])
@@ -48,9 +49,10 @@ struct cgit_filter *new_filter(const char *cmd, filter_type filtertype)
48 49
49 f = xmalloc(sizeof(struct cgit_filter)); 50 f = xmalloc(sizeof(struct cgit_filter));
50 f->cmd = xstrdup(cmd); 51 f->cmd = xstrdup(cmd);
51 f->argv = xmalloc((2 + extra_args) * sizeof(char *)); 52 args_size = (2 + extra_args) * sizeof(char *);
53 f->argv = xmalloc(args_size);
54 memset(f->argv, 0, args_size);
52 f->argv[0] = f->cmd; 55 f->argv[0] = f->cmd;
53 f->argv[1] = NULL;
54 return f; 56 return f;
55} 57}
56 58
@@ -158,6 +160,8 @@ void config_cb(const char *name, const char *value)
158 ctx.cfg.enable_filter_overrides = atoi(value); 160 ctx.cfg.enable_filter_overrides = atoi(value);
159 else if (!strcmp(name, "enable-gitweb-owner")) 161 else if (!strcmp(name, "enable-gitweb-owner"))
160 ctx.cfg.enable_gitweb_owner = atoi(value); 162 ctx.cfg.enable_gitweb_owner = atoi(value);
163 else if (!strcmp(name, "enable-http-clone"))
164 ctx.cfg.enable_http_clone = atoi(value);
161 else if (!strcmp(name, "enable-index-links")) 165 else if (!strcmp(name, "enable-index-links"))
162 ctx.cfg.enable_index_links = atoi(value); 166 ctx.cfg.enable_index_links = atoi(value);
163 else if (!strcmp(name, "enable-commit-graph")) 167 else if (!strcmp(name, "enable-commit-graph"))
@@ -323,6 +327,7 @@ static void prepare_context(struct cgit_context *ctx)
323 ctx->cfg.logo = "/cgit.png"; 327 ctx->cfg.logo = "/cgit.png";
324 ctx->cfg.local_time = 0; 328 ctx->cfg.local_time = 0;
325 ctx->cfg.enable_gitweb_owner = 1; 329 ctx->cfg.enable_gitweb_owner = 1;
330 ctx->cfg.enable_http_clone = 1;
326 ctx->cfg.enable_tree_linenumbers = 1; 331 ctx->cfg.enable_tree_linenumbers = 1;
327 ctx->cfg.max_repo_count = 50; 332 ctx->cfg.max_repo_count = 50;
328 ctx->cfg.max_commit_count = 50; 333 ctx->cfg.max_commit_count = 50;
@@ -450,7 +455,7 @@ static int prepare_repo_cmd(struct cgit_context *ctx)
450 tmp = xstrdup(ctx->qry.head); 455 tmp = xstrdup(ctx->qry.head);
451 ctx->qry.head = ctx->repo->defbranch; 456 ctx->qry.head = ctx->repo->defbranch;
452 ctx->page.status = 404; 457 ctx->page.status = 404;
453 ctx->page.statusmsg = "not found"; 458 ctx->page.statusmsg = "Not found";
454 cgit_print_http_headers(ctx); 459 cgit_print_http_headers(ctx);
455 cgit_print_docstart(ctx); 460 cgit_print_docstart(ctx);
456 cgit_print_pageheader(ctx); 461 cgit_print_pageheader(ctx);
@@ -469,6 +474,8 @@ static void process_request(void *cbdata)
469 cmd = cgit_get_cmd(ctx); 474 cmd = cgit_get_cmd(ctx);
470 if (!cmd) { 475 if (!cmd) {
471 ctx->page.title = "cgit error"; 476 ctx->page.title = "cgit error";
477 ctx->page.status = 404;
478 ctx->page.statusmsg = "Not found";
472 cgit_print_http_headers(ctx); 479 cgit_print_http_headers(ctx);
473 cgit_print_docstart(ctx); 480 cgit_print_docstart(ctx);
474 cgit_print_pageheader(ctx); 481 cgit_print_pageheader(ctx);
@@ -477,6 +484,11 @@ static void process_request(void *cbdata)
477 return; 484 return;
478 } 485 }
479 486
487 if (!ctx->cfg.enable_http_clone && cmd->is_clone) {
488 html_status(404, "Not found", 0);
489 return;
490 }
491
480 /* If cmd->want_vpath is set, assume ctx->qry.path contains a "virtual" 492 /* If cmd->want_vpath is set, assume ctx->qry.path contains a "virtual"
481 * in-project path limit to be made available at ctx->qry.vpath. 493 * in-project path limit to be made available at ctx->qry.vpath.
482 * Otherwise, no path limit is in effect (ctx->qry.vpath = NULL). 494 * Otherwise, no path limit is in effect (ctx->qry.vpath = NULL).
@@ -768,8 +780,11 @@ int main(int argc, const char **argv)
768 * that virtual-root equals SCRIPT_NAME, minus any possibly 780 * that virtual-root equals SCRIPT_NAME, minus any possibly
769 * trailing slashes. 781 * trailing slashes.
770 */ 782 */
771 if (!ctx.cfg.virtual_root) 783 if (!ctx.cfg.virtual_root && ctx.cfg.script_name) {
772 ctx.cfg.virtual_root = trim_end(ctx.cfg.script_name, '/'); 784 ctx.cfg.virtual_root = trim_end(ctx.cfg.script_name, '/');
785 if (!ctx.cfg.virtual_root)
786 ctx.cfg.virtual_root = "";
787 }
773 788
774 /* If no url parameter is specified on the querystring, lets 789 /* If no url parameter is specified on the querystring, lets
775 * use PATH_INFO as url. This allows cgit to work with virtual 790 * use PATH_INFO as url. This allows cgit to work with virtual
diff --git a/cgit.h b/cgit.h
index 3b0eaf5..caa9d8e 100644
--- a/cgit.h
+++ b/cgit.h
@@ -195,6 +195,7 @@ struct cgit_config {
195 int embedded; 195 int embedded;
196 int enable_filter_overrides; 196 int enable_filter_overrides;
197 int enable_gitweb_owner; 197 int enable_gitweb_owner;
198 int enable_http_clone;
198 int enable_index_links; 199 int enable_index_links;
199 int enable_commit_graph; 200 int enable_commit_graph;
200 int enable_log_filecount; 201 int enable_log_filecount;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 60539d7..5903a93 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -106,6 +106,11 @@ enable-gitweb-owner::
106 for the git config value "gitweb.owner" to determine the owner. 106 for the git config value "gitweb.owner" to determine the owner.
107 Default value: "1". See also: scan-path. 107 Default value: "1". See also: scan-path.
108 108
109enable-http-clone::
110 If set to "1", cgit will act as an dumb HTTP endpoint for git clones.
111 If you use an alternate way of serving git repositories, you may wish
112 to disable this. Default value: "1".
113
109enable-index-links:: 114enable-index-links::
110 Flag which, when set to "1", will make cgit generate extra links for 115 Flag which, when set to "1", will make cgit generate extra links for
111 each repo in the repository index (specifically, to the "summary", 116 each repo in the repository index (specifically, to the "summary",
@@ -288,8 +293,9 @@ scan-path::
288 the result will be cached as a cgitrc include-file in the cache 293 the result will be cached as a cgitrc include-file in the cache
289 directory. If project-list has been defined prior to scan-path, 294 directory. If project-list has been defined prior to scan-path,
290 scan-path loads only the directories listed in the file pointed to by 295 scan-path loads only the directories listed in the file pointed to by
291 project-list. Default value: none. See also: cache-scanrc-ttl, 296 project-list. Be advised that only the global settings taken
292 project-list. 297 before the scan-path directive will be applied to each repository.
298 Default value: none. See also: cache-scanrc-ttl, project-list.
293 299
294section:: 300section::
295 The name of the current repository section - all repositories defined 301 The name of the current repository section - all repositories defined
@@ -309,7 +315,8 @@ side-by-side-diffs::
309snapshots:: 315snapshots::
310 Text which specifies the default set of snapshot formats generated by 316 Text which specifies the default set of snapshot formats generated by
311 cgit. The value is a space-separated list of zero or more of the 317 cgit. The value is a space-separated list of zero or more of the
312 values "tar", "tar.gz", "tar.bz2" and "zip". Default value: none. 318 values "tar", "tar.gz", "tar.bz2", "tar.xz" and "zip". Default value:
319 none.
313 320
314source-filter:: 321source-filter::
315 Specifies a command which will be invoked to format plaintext blobs 322 Specifies a command which will be invoked to format plaintext blobs
diff --git a/cmd.c b/cmd.c
index 536515b..d114eb3 100644
--- a/cmd.c
+++ b/cmd.c
@@ -130,31 +130,31 @@ static void tree_fn(struct cgit_context *ctx)
130 cgit_print_tree(ctx->qry.sha1, ctx->qry.path); 130 cgit_print_tree(ctx->qry.sha1, ctx->qry.path);
131} 131}
132 132
133#define def_cmd(name, want_repo, want_layout, want_vpath) \ 133#define def_cmd(name, want_repo, want_layout, want_vpath, is_clone) \
134 {#name, name##_fn, want_repo, want_layout, want_vpath} 134 {#name, name##_fn, want_repo, want_layout, want_vpath, is_clone}
135 135
136struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx) 136struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx)
137{ 137{
138 static struct cgit_cmd cmds[] = { 138 static struct cgit_cmd cmds[] = {
139 def_cmd(HEAD, 1, 0, 0), 139 def_cmd(HEAD, 1, 0, 0, 1),
140 def_cmd(atom, 1, 0, 0), 140 def_cmd(atom, 1, 0, 0, 0),
141 def_cmd(about, 0, 1, 0), 141 def_cmd(about, 0, 1, 0, 0),
142 def_cmd(blob, 1, 0, 0), 142 def_cmd(blob, 1, 0, 0, 0),
143 def_cmd(commit, 1, 1, 1), 143 def_cmd(commit, 1, 1, 1, 0),
144 def_cmd(diff, 1, 1, 1), 144 def_cmd(diff, 1, 1, 1, 0),
145 def_cmd(info, 1, 0, 0), 145 def_cmd(info, 1, 0, 0, 1),
146 def_cmd(log, 1, 1, 1), 146 def_cmd(log, 1, 1, 1, 0),
147 def_cmd(ls_cache, 0, 0, 0), 147 def_cmd(ls_cache, 0, 0, 0, 0),
148 def_cmd(objects, 1, 0, 0), 148 def_cmd(objects, 1, 0, 0, 1),
149 def_cmd(patch, 1, 0, 1), 149 def_cmd(patch, 1, 0, 1, 0),
150 def_cmd(plain, 1, 0, 0), 150 def_cmd(plain, 1, 0, 0, 0),
151 def_cmd(refs, 1, 1, 0), 151 def_cmd(refs, 1, 1, 0, 0),
152 def_cmd(repolist, 0, 0, 0), 152 def_cmd(repolist, 0, 0, 0, 0),
153 def_cmd(snapshot, 1, 0, 0), 153 def_cmd(snapshot, 1, 0, 0, 0),
154 def_cmd(stats, 1, 1, 1), 154 def_cmd(stats, 1, 1, 1, 0),
155 def_cmd(summary, 1, 1, 0), 155 def_cmd(summary, 1, 1, 0, 0),
156 def_cmd(tag, 1, 1, 0), 156 def_cmd(tag, 1, 1, 0, 0),
157 def_cmd(tree, 1, 1, 1), 157 def_cmd(tree, 1, 1, 1, 0),
158 }; 158 };
159 int i; 159 int i;
160 160
diff --git a/cmd.h b/cmd.h
index 8dc01bd..eb5bc87 100644
--- a/cmd.h
+++ b/cmd.h
@@ -8,7 +8,8 @@ struct cgit_cmd {
8 cgit_cmd_fn fn; 8 cgit_cmd_fn fn;
9 unsigned int want_repo:1, 9 unsigned int want_repo:1,
10 want_layout:1, 10 want_layout:1,
11 want_vpath:1; 11 want_vpath:1,
12 is_clone:1;
12}; 13};
13 14
14extern struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx); 15extern struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx);
diff --git a/html.c b/html.c
index a60bc13..a0f6db4 100644
--- a/html.c
+++ b/html.c
@@ -18,7 +18,7 @@ static const char* url_escape_table[256] = {
18 "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", "%08", "%09", 18 "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", "%08", "%09",
19 "%0a", "%0b", "%0c", "%0d", "%0e", "%0f", "%10", "%11", "%12", "%13", 19 "%0a", "%0b", "%0c", "%0d", "%0e", "%0f", "%10", "%11", "%12", "%13",
20 "%14", "%15", "%16", "%17", "%18", "%19", "%1a", "%1b", "%1c", "%1d", 20 "%14", "%15", "%16", "%17", "%18", "%19", "%1a", "%1b", "%1c", "%1d",
21 "%1e", "%1f", "+", 0, "%22", "%23", 0, "%25", "%26", "%27", 0, 0, 0, 21 "%1e", "%1f", "%20", 0, "%22", "%23", 0, "%25", "%26", "%27", 0, 0, 0,
22 "%2b", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "%3c", "%3d", 22 "%2b", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "%3c", "%3d",
23 "%3e", "%3f", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23 "%3e", "%3f", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24 0, 0, 0, 0, 0, 0, 0, 0, 0, "%5c", 0, "%5e", 0, "%60", 0, 0, 0, 0, 0, 24 0, 0, 0, 0, 0, 0, 0, 0, 0, "%5c", 0, "%5e", 0, "%60", 0, 0, 0, 0, 0,
@@ -162,9 +162,9 @@ void html_url_path(const char *txt)
162 while(t && *t){ 162 while(t && *t){
163 int c = *t; 163 int c = *t;
164 const char *e = url_escape_table[c]; 164 const char *e = url_escape_table[c];
165 if (e && c!='+' && c!='&' && c!='+') { 165 if (e && c!='+' && c!='&') {
166 html_raw(txt, t - txt); 166 html_raw(txt, t - txt);
167 html_raw(e, 3); 167 html(e);
168 txt = t+1; 168 txt = t+1;
169 } 169 }
170 t++; 170 t++;
@@ -179,9 +179,11 @@ void html_url_arg(const char *txt)
179 while(t && *t){ 179 while(t && *t){
180 int c = *t; 180 int c = *t;
181 const char *e = url_escape_table[c]; 181 const char *e = url_escape_table[c];
182 if (c == ' ')
183 e = "+";
182 if (e) { 184 if (e) {
183 html_raw(txt, t - txt); 185 html_raw(txt, t - txt);
184 html_raw(e, strlen(e)); 186 html(e);
185 txt = t+1; 187 txt = t+1;
186 } 188 }
187 t++; 189 t++;
@@ -288,12 +290,12 @@ char *convert_query_hexchar(char *txt)
288 290
289int http_parse_querystring(const char *txt_, void (*fn)(const char *name, const char *value)) 291int http_parse_querystring(const char *txt_, void (*fn)(const char *name, const char *value))
290{ 292{
291 char *t, *txt, *value = NULL, c; 293 char *o, *t, *txt, *value = NULL, c;
292 294
293 if (!txt_) 295 if (!txt_)
294 return 0; 296 return 0;
295 297
296 t = txt = strdup(txt_); 298 o = t = txt = strdup(txt_);
297 if (t == NULL) { 299 if (t == NULL) {
298 printf("Out of memory\n"); 300 printf("Out of memory\n");
299 exit(1); 301 exit(1);
@@ -316,5 +318,6 @@ int http_parse_querystring(const char *txt_, void (*fn)(const char *name, const
316 } 318 }
317 if (t!=txt) 319 if (t!=txt)
318 (*fn)(txt, value); 320 (*fn)(txt, value);
321 free(o);
319 return 0; 322 return 0;
320} 323}
diff --git a/parsing.c b/parsing.c
index f37c49d..151c0fe 100644
--- a/parsing.c
+++ b/parsing.c
@@ -103,10 +103,17 @@ const char *reencode(char **txt, const char *src_enc, const char *dst_enc)
103{ 103{
104 char *tmp; 104 char *tmp;
105 105
106 if (!txt || !*txt || !src_enc || !dst_enc) 106 if (!txt)
107 return NULL;
108
109 if (!*txt || !src_enc || !dst_enc)
110 return *txt;
111
112 /* no encoding needed if src_enc equals dst_enc */
113 if(!strcasecmp(src_enc, dst_enc))
107 return *txt; 114 return *txt;
108 115
109 tmp = reencode_string(*txt, src_enc, dst_enc);