diff options
Diffstat (limited to 'cgit.c')
-rw-r--r-- | cgit.c | 92 |
1 files changed, 69 insertions, 23 deletions
@@ -1,7 +1,7 @@ | |||
1 | /* cgit.c: cgi for the git scm | 1 | /* cgit.c: cgi for the git scm |
2 | * | 2 | * |
3 | * Copyright (C) 2006 Lars Hjemli | 3 | * Copyright (C) 2006 Lars Hjemli |
4 | * Copyright (C) 2010, 2012 Jason A. Donenfeld <Jason@zx2c4.com> | 4 | * Copyright (C) 2010-2013 Jason A. Donenfeld <Jason@zx2c4.com> |
5 | * | 5 | * |
6 | * Licensed under GNU General Public License v2 | 6 | * Licensed under GNU General Public License v2 |
7 | * (see COPYING for full license text) | 7 | * (see COPYING for full license text) |
@@ -101,13 +101,15 @@ static void repo_config(struct cgit_repo *repo, const char *name, const char *va | |||
101 | else if (!strcmp(name, "module-link")) | 101 | else if (!strcmp(name, "module-link")) |
102 | repo->module_link= xstrdup(value); | 102 | repo->module_link= xstrdup(value); |
103 | else if (!prefixcmp(name, "module-link.")) { | 103 | else if (!prefixcmp(name, "module-link.")) { |
104 | item = string_list_append(&repo->submodules, name + 12); | 104 | item = string_list_append(&repo->submodules, xstrdup(name + 12)); |
105 | item->util = xstrdup(value); | 105 | item->util = xstrdup(value); |
106 | } else if (!strcmp(name, "section")) | 106 | } else if (!strcmp(name, "section")) |
107 | repo->section = xstrdup(value); | 107 | repo->section = xstrdup(value); |
108 | else if (!strcmp(name, "readme") && value != NULL) | 108 | else if (!strcmp(name, "readme") && value != NULL) { |
109 | repo->readme = xstrdup(value); | 109 | if (repo->readme.items == ctx.cfg.readme.items) |
110 | else if (!strcmp(name, "logo") && value != NULL) | 110 | memset(&repo->readme, 0, sizeof(repo->readme)); |
111 | string_list_append(&repo->readme, xstrdup(value)); | ||
112 | } else if (!strcmp(name, "logo") && value != NULL) | ||
111 | repo->logo = xstrdup(value); | 113 | repo->logo = xstrdup(value); |
112 | else if (!strcmp(name, "logo-link") && value != NULL) | 114 | else if (!strcmp(name, "logo-link") && value != NULL) |
113 | repo->logo_link = xstrdup(value); | 115 | repo->logo_link = xstrdup(value); |
@@ -131,8 +133,8 @@ static void config_cb(const char *name, const char *value) | |||
131 | ctx.repo->path = trim_end(value, '/'); | 133 | ctx.repo->path = trim_end(value, '/'); |
132 | else if (ctx.repo && !prefixcmp(name, "repo.")) | 134 | else if (ctx.repo && !prefixcmp(name, "repo.")) |
133 | repo_config(ctx.repo, name + 5, value); | 135 | repo_config(ctx.repo, name + 5, value); |
134 | else if (!strcmp(name, "readme")) | 136 | else if (!strcmp(name, "readme") && value != NULL) |
135 | ctx.cfg.readme = xstrdup(value); | 137 | string_list_append(&ctx.cfg.readme, xstrdup(value)); |
136 | else if (!strcmp(name, "root-title")) | 138 | else if (!strcmp(name, "root-title")) |
137 | ctx.cfg.root_title = xstrdup(value); | 139 | ctx.cfg.root_title = xstrdup(value); |
138 | else if (!strcmp(name, "root-desc")) | 140 | else if (!strcmp(name, "root-desc")) |
@@ -470,37 +472,76 @@ static char *guess_defbranch(void) | |||
470 | return "master"; | 472 | return "master"; |
471 | return xstrdup(ref + 11); | 473 | return xstrdup(ref + 11); |
472 | } | 474 | } |
475 | /* The caller must free filename and ref after calling this. */ | ||
476 | static inline void parse_readme(const char *readme, char **filename, char **ref, struct cgit_repo *repo) | ||
477 | { | ||
478 | const char *colon; | ||
479 | |||
480 | *filename = NULL; | ||
481 | *ref = NULL; | ||
482 | |||
483 | if (!readme || !readme[0]) | ||
484 | return; | ||
473 | 485 | ||
486 | /* Check if the readme is tracked in the git repo. */ | ||
487 | colon = strchr(readme, ':'); | ||
488 | if (colon && strlen(colon) > 1) { | ||
489 | /* If it starts with a colon, we want to use | ||
490 | * the default branch */ | ||
491 | if (colon == readme && repo->defbranch) | ||
492 | *ref = xstrdup(repo->defbranch); | ||
493 | else | ||
494 | *ref = xstrndup(readme, colon - readme); | ||
495 | readme = colon + 1; | ||
496 | } | ||
497 | |||
498 | /* Prepend repo path to relative readme path unless tracked. */ | ||
499 | if (!(*ref) && readme[0] != '/') | ||
500 | *filename = fmtalloc("%s/%s", repo->path, readme); | ||
501 | else | ||
502 | *filename = xstrdup(readme); | ||
503 | } | ||
474 | static void choose_readme(struct cgit_repo *repo) | 504 | static void choose_readme(struct cgit_repo *repo) |
475 | { | 505 | { |
476 | char *entry, *filename, *ref; | 506 | int found; |
507 | char *filename, *ref; | ||
508 | struct string_list_item *entry; | ||
477 | 509 | ||
478 | /* If there's no space, we skip the possibly expensive | 510 | if (!repo->readme.nr) |
479 | * selection process. */ | ||
480 | if (!repo->readme || !strchr(repo->readme, ' ')) | ||
481 | return; | 511 | return; |
482 | 512 | ||
483 | for (entry = strtok(repo->readme, " "); entry; entry = strtok(NULL, " ")) { | 513 | found = 0; |
484 | cgit_parse_readme(entry, NULL, &filename, &ref, repo); | 514 | for_each_string_list_item(entry, &repo->readme) { |
485 | if (!(*filename)) { | 515 | parse_readme(entry->string, &filename, &ref, repo); |
516 | if (!filename) { | ||
486 | free(filename); | 517 | free(filename); |
487 | free(ref); | 518 | free(ref); |
488 | continue; | 519 | continue; |
489 | } | 520 | } |
490 | if (*ref && cgit_ref_path_exists(filename, ref)) { | 521 | /* If there's only one item, we skip the possibly expensive |
491 | free(filename); | 522 | * selection process. */ |
492 | free(ref); | 523 | if (repo->readme.nr == 1) { |
524 | found = 1; | ||
493 | break; | 525 | break; |
494 | } | 526 | } |
495 | if (!access(filename, R_OK)) { | 527 | if (ref) { |
496 | free(filename); | 528 | if (cgit_ref_path_exists(filename, ref, 1)) { |
497 | free(ref); | 529 | found = 1; |
530 | break; | ||
531 | } | ||
532 | } | ||
533 | else if (!access(filename, R_OK)) { | ||
534 | found = 1; | ||
498 | break; | 535 | break; |
499 | } | 536 | } |
500 | free(filename); | 537 | free(filename); |
501 | free(ref); | 538 | free(ref); |
502 | } | 539 | } |
503 | repo->readme = entry; | 540 | repo->readme.strdup_strings = 1; |
541 | string_list_clear(&repo->readme, 0); | ||
542 | repo->readme.strdup_strings = 0; | ||
543 | if (found) | ||
544 | string_list_append(&repo->readme, filename)->util = ref; | ||
504 | } | 545 | } |
505 | 546 | ||
506 | static int prepare_repo_cmd(struct cgit_context *ctx) | 547 | static int prepare_repo_cmd(struct cgit_context *ctx) |
@@ -660,6 +701,7 @@ static char *get_first_line(char *txt) | |||
660 | 701 | ||
661 | static void print_repo(FILE *f, struct cgit_repo *repo) | 702 | static void print_repo(FILE *f, struct cgit_repo *repo) |
662 | { | 703 | { |
704 | struct string_list_item *item; | ||
663 | fprintf(f, "repo.url=%s\n", repo->url); | 705 | fprintf(f, "repo.url=%s\n", repo->url); |
664 | fprintf(f, "repo.name=%s\n", repo->name); | 706 | fprintf(f, "repo.name=%s\n", repo->name); |
665 | fprintf(f, "repo.path=%s\n", repo->path); | 707 | fprintf(f, "repo.path=%s\n", repo->path); |
@@ -670,8 +712,12 @@ static void print_repo(FILE *f, struct cgit_repo *repo) | |||
670 | fprintf(f, "repo.desc=%s\n", tmp); | 712 | fprintf(f, "repo.desc=%s\n", tmp); |
671 | free(tmp); | 713 | free(tmp); |
672 | } | 714 | } |
673 | if (repo->readme) | 715 | for_each_string_list_item(item, &repo->readme) { |
674 | fprintf(f, "repo.readme=%s\n", repo->readme); | 716 | if (item->util) |
717 | fprintf(f, "repo.readme=%s:%s\n", (char *)item->util, item->string); | ||
718 | else | ||
719 | fprintf(f, "repo.readme=%s\n", item->string); | ||
720 | } | ||
675 | if (repo->defbranch) | 721 | if (repo->defbranch) |
676 | fprintf(f, "repo.defbranch=%s\n", repo->defbranch); | 722 | fprintf(f, "repo.defbranch=%s\n", repo->defbranch); |
677 | if (repo->module_link) | 723 | if (repo->module_link) |