author | Lars Hjemli <hjemli@gmail.com> | 2010-07-18 13:03:08 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2010-07-18 13:03:08 (UTC) |
commit | 5c5d189635287a3bfaa1a4aef133dc0c582a27c2 (patch) (unidiff) | |
tree | cf14b0a5578c9d23a560690e7e256260633ce043 | |
parent | 60fcf600f5010701c20b63867999a802ca0e05c0 (diff) | |
parent | ba56a37e863d0f90e3e953047486905cfb959925 (diff) | |
download | cgit-5c5d189635287a3bfaa1a4aef133dc0c582a27c2.zip cgit-5c5d189635287a3bfaa1a4aef133dc0c582a27c2.tar.gz cgit-5c5d189635287a3bfaa1a4aef133dc0c582a27c2.tar.bz2 |
Merge branch 'lh/macros'
-rw-r--r-- | cgit.c | 10 | ||||
-rw-r--r-- | cgit.h | 2 | ||||
-rw-r--r-- | shared.c | 71 |
3 files changed, 78 insertions, 5 deletions
@@ -143,25 +143,25 @@ void config_cb(const char *name, const char *value) | |||
143 | ctx.cfg.enable_log_linecount = atoi(value); | 143 | ctx.cfg.enable_log_linecount = atoi(value); |
144 | else if (!strcmp(name, "enable-remote-branches")) | 144 | else if (!strcmp(name, "enable-remote-branches")) |
145 | ctx.cfg.enable_remote_branches = atoi(value); | 145 | ctx.cfg.enable_remote_branches = atoi(value); |
146 | else if (!strcmp(name, "enable-subject-links")) | 146 | else if (!strcmp(name, "enable-subject-links")) |
147 | ctx.cfg.enable_subject_links = atoi(value); | 147 | ctx.cfg.enable_subject_links = atoi(value); |
148 | else if (!strcmp(name, "enable-tree-linenumbers")) | 148 | else if (!strcmp(name, "enable-tree-linenumbers")) |
149 | ctx.cfg.enable_tree_linenumbers = atoi(value); | 149 | ctx.cfg.enable_tree_linenumbers = atoi(value); |
150 | else if (!strcmp(name, "max-stats")) | 150 | else if (!strcmp(name, "max-stats")) |
151 | ctx.cfg.max_stats = cgit_find_stats_period(value, NULL); | 151 | ctx.cfg.max_stats = cgit_find_stats_period(value, NULL); |
152 | else if (!strcmp(name, "cache-size")) | 152 | else if (!strcmp(name, "cache-size")) |
153 | ctx.cfg.cache_size = atoi(value); | 153 | ctx.cfg.cache_size = atoi(value); |
154 | else if (!strcmp(name, "cache-root")) | 154 | else if (!strcmp(name, "cache-root")) |
155 | ctx.cfg.cache_root = xstrdup(value); | 155 | ctx.cfg.cache_root = xstrdup(expand_macros(value)); |
156 | else if (!strcmp(name, "cache-root-ttl")) | 156 | else if (!strcmp(name, "cache-root-ttl")) |
157 | ctx.cfg.cache_root_ttl = atoi(value); | 157 | ctx.cfg.cache_root_ttl = atoi(value); |
158 | else if (!strcmp(name, "cache-repo-ttl")) | 158 | else if (!strcmp(name, "cache-repo-ttl")) |
159 | ctx.cfg.cache_repo_ttl = atoi(value); | 159 | ctx.cfg.cache_repo_ttl = atoi(value); |
160 | else if (!strcmp(name, "cache-scanrc-ttl")) | 160 | else if (!strcmp(name, "cache-scanrc-ttl")) |
161 | ctx.cfg.cache_scanrc_ttl = atoi(value); | 161 | ctx.cfg.cache_scanrc_ttl = atoi(value); |
162 | else if (!strcmp(name, "cache-static-ttl")) | 162 | else if (!strcmp(name, "cache-static-ttl")) |
163 | ctx.cfg.cache_static_ttl = atoi(value); | 163 | ctx.cfg.cache_static_ttl = atoi(value); |
164 | else if (!strcmp(name, "cache-dynamic-ttl")) | 164 | else if (!strcmp(name, "cache-dynamic-ttl")) |
165 | ctx.cfg.cache_dynamic_ttl = atoi(value); | 165 | ctx.cfg.cache_dynamic_ttl = atoi(value); |
166 | else if (!strcmp(name, "about-filter")) | 166 | else if (!strcmp(name, "about-filter")) |
167 | ctx.cfg.about_filter = new_filter(value, 0); | 167 | ctx.cfg.about_filter = new_filter(value, 0); |
@@ -174,51 +174,51 @@ void config_cb(const char *name, const char *value) | |||
174 | else if (!strcmp(name, "max-message-length")) | 174 | else if (!strcmp(name, "max-message-length")) |
175 | ctx.cfg.max_msg_len = atoi(value); | 175 | ctx.cfg.max_msg_len = atoi(value); |
176 | else if (!strcmp(name, "max-repodesc-length")) | 176 | else if (!strcmp(name, "max-repodesc-length")) |
177 | ctx.cfg.max_repodesc_len = atoi(value); | 177 | ctx.cfg.max_repodesc_len = atoi(value); |
178 | else if (!strcmp(name, "max-blob-size")) | 178 | else if (!strcmp(name, "max-blob-size")) |
179 | ctx.cfg.max_blob_size = atoi(value); | 179 | ctx.cfg.max_blob_size = atoi(value); |
180 | else if (!strcmp(name, "max-repo-count")) | 180 | else if (!strcmp(name, "max-repo-count")) |
181 | ctx.cfg.max_repo_count = atoi(value); | 181 | ctx.cfg.max_repo_count = atoi(value); |
182 | else if (!strcmp(name, "max-commit-count")) | 182 | else if (!strcmp(name, "max-commit-count")) |
183 | ctx.cfg.max_commit_count = atoi(value); | 183 | ctx.cfg.max_commit_count = atoi(value); |
184 | else if (!strcmp(name, "scan-path")) | 184 | else if (!strcmp(name, "scan-path")) |
185 | if (!ctx.cfg.nocache && ctx.cfg.cache_size) | 185 | if (!ctx.cfg.nocache && ctx.cfg.cache_size) |
186 | process_cached_repolist(value); | 186 | process_cached_repolist(expand_macros(value)); |
187 | else | 187 | else |
188 | scan_tree(value, repo_config); | 188 | scan_tree(expand_macros(value), repo_config); |
189 | else if (!strcmp(name, "source-filter")) | 189 | else if (!strcmp(name, "source-filter")) |
190 | ctx.cfg.source_filter = new_filter(value, 1); | 190 | ctx.cfg.source_filter = new_filter(value, 1); |
191 | else if (!strcmp(name, "summary-log")) | 191 | else if (!strcmp(name, "summary-log")) |
192 | ctx.cfg.summary_log = atoi(value); | 192 | ctx.cfg.summary_log = atoi(value); |
193 | else if (!strcmp(name, "summary-branches")) | 193 | else if (!strcmp(name, "summary-branches")) |
194 | ctx.cfg.summary_branches = atoi(value); | 194 | ctx.cfg.summary_branches = atoi(value); |
195 | else if (!strcmp(name, "summary-tags")) | 195 | else if (!strcmp(name, "summary-tags")) |
196 | ctx.cfg.summary_tags = atoi(value); | 196 | ctx.cfg.summary_tags = atoi(value); |
197 | else if (!strcmp(name, "side-by-side-diffs")) | 197 | else if (!strcmp(name, "side-by-side-diffs")) |
198 | ctx.cfg.ssdiff = atoi(value); | 198 | ctx.cfg.ssdiff = atoi(value); |
199 | else if (!strcmp(name, "agefile")) | 199 | else if (!strcmp(name, "agefile")) |
200 | ctx.cfg.agefile = xstrdup(value); | 200 | ctx.cfg.agefile = xstrdup(value); |
201 | else if (!strcmp(name, "renamelimit")) | 201 | else if (!strcmp(name, "renamelimit")) |
202 | ctx.cfg.renamelimit = atoi(value); | 202 | ctx.cfg.renamelimit = atoi(value); |
203 | else if (!strcmp(name, "robots")) | 203 | else if (!strcmp(name, "robots")) |
204 | ctx.cfg.robots = xstrdup(value); | 204 | ctx.cfg.robots = xstrdup(value); |
205 | else if (!strcmp(name, "clone-prefix")) | 205 | else if (!strcmp(name, "clone-prefix")) |
206 | ctx.cfg.clone_prefix = xstrdup(value); | 206 | ctx.cfg.clone_prefix = xstrdup(value); |
207 | else if (!strcmp(name, "local-time")) | 207 | else if (!strcmp(name, "local-time")) |
208 | ctx.cfg.local_time = atoi(value); | 208 | ctx.cfg.local_time = atoi(value); |
209 | else if (!prefixcmp(name, "mimetype.")) | 209 | else if (!prefixcmp(name, "mimetype.")) |
210 | add_mimetype(name + 9, value); | 210 | add_mimetype(name + 9, value); |
211 | else if (!strcmp(name, "include")) | 211 | else if (!strcmp(name, "include")) |
212 | parse_configfile(value, config_cb); | 212 | parse_configfile(expand_macros(value), config_cb); |
213 | } | 213 | } |
214 | 214 | ||
215 | static void querystring_cb(const char *name, const char *value) | 215 | static void querystring_cb(const char *name, const char *value) |
216 | { | 216 | { |
217 | if (!value) | 217 | if (!value) |
218 | value = ""; | 218 | value = ""; |
219 | 219 | ||
220 | if (!strcmp(name,"r")) { | 220 | if (!strcmp(name,"r")) { |
221 | ctx.qry.repo = xstrdup(value); | 221 | ctx.qry.repo = xstrdup(value); |
222 | ctx.repo = cgit_get_repoinfo(value); | 222 | ctx.repo = cgit_get_repoinfo(value); |
223 | } else if (!strcmp(name, "p")) { | 223 | } else if (!strcmp(name, "p")) { |
224 | ctx.qry.page = xstrdup(value); | 224 | ctx.qry.page = xstrdup(value); |
@@ -696,25 +696,25 @@ static int calc_ttl() | |||
696 | int main(int argc, const char **argv) | 696 | int main(int argc, const char **argv) |
697 | { | 697 | { |
698 | const char *path; | 698 | const char *path; |
699 | char *qry; | 699 | char *qry; |
700 | int err, ttl; | 700 | int err, ttl; |
701 | 701 | ||
702 | prepare_context(&ctx); | 702 | prepare_context(&ctx); |
703 | cgit_repolist.length = 0; | 703 | cgit_repolist.length = 0; |
704 | cgit_repolist.count = 0; | 704 | cgit_repolist.count = 0; |
705 | cgit_repolist.repos = NULL; | 705 | cgit_repolist.repos = NULL; |
706 | 706 | ||
707 | cgit_parse_args(argc, argv); | 707 | cgit_parse_args(argc, argv); |
708 | parse_configfile(ctx.env.cgit_config, config_cb); | 708 | parse_configfile(expand_macros(ctx.env.cgit_config), config_cb); |
709 | ctx.repo = NULL; | 709 | ctx.repo = NULL; |
710 | http_parse_querystring(ctx.qry.raw, querystring_cb); | 710 | http_parse_querystring(ctx.qry.raw, querystring_cb); |
711 | 711 | ||
712 | /* If virtual-root isn't specified in cgitrc, lets pretend | 712 | /* If virtual-root isn't specified in cgitrc, lets pretend |
713 | * that virtual-root equals SCRIPT_NAME. | 713 | * that virtual-root equals SCRIPT_NAME. |
714 | */ | 714 | */ |
715 | if (!ctx.cfg.virtual_root) | 715 | if (!ctx.cfg.virtual_root) |
716 | ctx.cfg.virtual_root = ctx.cfg.script_name; | 716 | ctx.cfg.virtual_root = ctx.cfg.script_name; |
717 | 717 | ||
718 | /* If no url parameter is specified on the querystring, lets | 718 | /* If no url parameter is specified on the querystring, lets |
719 | * use PATH_INFO as url. This allows cgit to work with virtual | 719 | * use PATH_INFO as url. This allows cgit to work with virtual |
720 | * urls without the need for rewriterules in the webserver (as | 720 | * urls without the need for rewriterules in the webserver (as |
@@ -293,13 +293,15 @@ extern struct commitinfo *cgit_parse_commit(struct commit *commit); | |||
293 | extern struct taginfo *cgit_parse_tag(struct tag *tag); | 293 | extern struct taginfo *cgit_parse_tag(struct tag *tag); |
294 | extern void cgit_parse_url(const char *url); | 294 | extern void cgit_parse_url(const char *url); |
295 | 295 | ||
296 | extern const char *cgit_repobasename(const char *reponame); | 296 | extern const char *cgit_repobasename(const char *reponame); |
297 | 297 | ||
298 | extern int cgit_parse_snapshots_mask(const char *str); | 298 | extern int cgit_parse_snapshots_mask(const char *str); |
299 | 299 | ||
300 | extern int cgit_open_filter(struct cgit_filter *filter); | 300 | extern int cgit_open_filter(struct cgit_filter *filter); |
301 | extern int cgit_close_filter(struct cgit_filter *filter); | 301 | extern int cgit_close_filter(struct cgit_filter *filter); |
302 | 302 | ||
303 | extern int readfile(const char *path, char **buf, size_t *size); | 303 | extern int readfile(const char *path, char **buf, size_t *size); |
304 | 304 | ||
305 | extern char *expand_macros(const char *txt); | ||
306 | |||
305 | #endif /* CGIT_H */ | 307 | #endif /* CGIT_H */ |
@@ -423,12 +423,83 @@ int readfile(const char *path, char **buf, size_t *size) | |||
423 | } | 423 | } |
424 | if (!S_ISREG(st.st_mode)) { | 424 | if (!S_ISREG(st.st_mode)) { |
425 | close(fd); | 425 | close(fd); |
426 | return EISDIR; | 426 | return EISDIR; |
427 | } | 427 | } |
428 | *buf = xmalloc(st.st_size + 1); | 428 | *buf = xmalloc(st.st_size + 1); |
429 | *size = read_in_full(fd, *buf, st.st_size); | 429 | *size = read_in_full(fd, *buf, st.st_size); |
430 | e = errno; | 430 | e = errno; |
431 | (*buf)[*size] = '\0'; | 431 | (*buf)[*size] = '\0'; |
432 | close(fd); | 432 | close(fd); |
433 | return (*size == st.st_size ? 0 : e); | 433 | return (*size == st.st_size ? 0 : e); |
434 | } | 434 | } |
435 | |||
436 | int is_token_char(char c) | ||
437 | { | ||
438 | return isalnum(c) || c == '_'; | ||
439 | } | ||
440 | |||
441 | /* Replace name with getenv(name), return pointer to zero-terminating char | ||
442 | */ | ||
443 | char *expand_macro(char *name, int maxlength) | ||
444 | { | ||
445 | char *value; | ||
446 | int len; | ||
447 | |||
448 | len = 0; | ||
449 | value = getenv(name); | ||
450 | if (value) { | ||
451 | len = strlen(value); | ||
452 | if (len > maxlength) | ||
453 | len = maxlength; | ||
454 | strncpy(name, value, len); | ||
455 | } | ||
456 | return name + len; | ||
457 | } | ||
458 | |||
459 | #define EXPBUFSIZE (1024 * 8) | ||
460 | |||
461 | /* Replace all tokens prefixed by '$' in the specified text with the | ||
462 | * value of the named environment variable. | ||
463 | * NB: the return value is a static buffer, i.e. it must be strdup'd | ||
464 | * by the caller. | ||
465 | */ | ||
466 | char *expand_macros(const char *txt) | ||
467 | { | ||
468 | static char result[EXPBUFSIZE]; | ||
469 | char *p, *start; | ||
470 | int len; | ||
471 | |||
472 | p = result; | ||
473 | start = NULL; | ||
474 | while (p < result + EXPBUFSIZE - 1 && txt && *txt) { | ||
475 | *p = *txt; | ||
476 | if (start) { | ||
477 | if (!is_token_char(*txt)) { | ||
478 | if (p - start > 0) { | ||
479 | *p = '\0'; | ||
480 | len = result + EXPBUFSIZE - start - 1; | ||
481 | p = expand_macro(start, len) - 1; | ||
482 | } | ||
483 | start = NULL; | ||
484 | txt--; | ||
485 | } | ||
486 | p++; | ||
487 | txt++; | ||
488 | continue; | ||
489 | } | ||
490 | if (*txt == '$') { | ||
491 | start = p; | ||
492 | txt++; | ||
493 | continue; | ||
494 | } | ||
495 | p++; | ||
496 | txt++; | ||
497 | } | ||
498 | *p = '\0'; | ||
499 | if (start && p - start > 0) { | ||
500 | len = result + EXPBUFSIZE - start - 1; | ||
501 | p = expand_macro(start, len); | ||
502 | *p = '\0'; | ||
503 | } | ||
504 | return result; | ||
505 | } | ||