diff options
| -rw-r--r-- | .gitignore | 5 | ||||
| -rw-r--r-- | Makefile | 21 | ||||
| -rw-r--r-- | cache.h | 2 | ||||
| -rw-r--r-- | cgit-doc.css | 3 | ||||
| -rw-r--r-- | cgit.c | 345 | ||||
| -rw-r--r-- | cgit.css | 10 | ||||
| -rw-r--r-- | cgit.h | 52 | ||||
| -rw-r--r-- | cgitrc.5.txt | 244 | ||||
| -rw-r--r-- | cmd.c | 2 | ||||
| -rwxr-xr-x | filters/commit-links.sh | 12 | ||||
| -rwxr-xr-x | filters/syntax-highlighting.sh | 39 | ||||
| m--------- | git | 0 | ||||
| -rw-r--r-- | scan-tree.c | 45 | ||||
| -rw-r--r-- | scan-tree.h | 2 | ||||
| -rw-r--r-- | shared.c | 62 | ||||
| -rw-r--r-- | ui-atom.c | 8 | ||||
| -rw-r--r-- | ui-blob.c | 8 | ||||
| -rw-r--r-- | ui-commit.c | 22 | ||||
| -rw-r--r-- | ui-log.c | 6 | ||||
| -rw-r--r-- | ui-patch.c | 6 | ||||
| -rw-r--r-- | ui-plain.c | 18 | ||||
| -rw-r--r-- | ui-refs.c | 19 | ||||
| -rw-r--r-- | ui-repolist.c | 65 | ||||
| -rw-r--r-- | ui-shared.c | 81 | ||||
| -rw-r--r-- | ui-shared.h | 1 | ||||
| -rw-r--r-- | ui-snapshot.c | 35 | ||||
| -rw-r--r-- | ui-stats.c | 8 | ||||
| -rw-r--r-- | ui-stats.h | 1 | ||||
| -rw-r--r-- | ui-summary.c | 28 | ||||
| -rw-r--r-- | ui-summary.h | 2 | ||||
| -rw-r--r-- | ui-tag.c | 2 | ||||
| -rw-r--r-- | ui-tree.c | 55 |
32 files changed, 942 insertions, 267 deletions
| @@ -2,5 +2,10 @@ | |||
| 2 | cgit | 2 | cgit |
| 3 | cgit.conf | 3 | cgit.conf |
| 4 | VERSION | 4 | VERSION |
| 5 | cgitrc.5 | ||
| 6 | cgitrc.5.fo | ||
| 7 | cgitrc.5.html | ||
| 8 | cgitrc.5.pdf | ||
| 9 | cgitrc.5.xml | ||
| 5 | *.o | 10 | *.o |
| 6 | *.d | 11 | *.d |
| @@ -5,7 +5,7 @@ CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH) | |||
| 5 | CGIT_CONFIG = /etc/cgitrc | 5 | CGIT_CONFIG = /etc/cgitrc |
| 6 | CACHE_ROOT = /var/cache/cgit | 6 | CACHE_ROOT = /var/cache/cgit |
| 7 | SHA1_HEADER = <openssl/sha.h> | 7 | SHA1_HEADER = <openssl/sha.h> |
| 8 | GIT_VER = 1.6.1.1 | 8 | GIT_VER = 1.6.4.3 |
| 9 | GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2 | 9 | GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2 |
| 10 | INSTALL = install | 10 | INSTALL = install |
| 11 | 11 | ||
| @@ -100,7 +100,8 @@ ifdef NEEDS_LIBICONV | |||
| 100 | endif | 100 | endif |
| 101 | 101 | ||
| 102 | 102 | ||
| 103 | .PHONY: all libgit test install uninstall clean force-version get-git | 103 | .PHONY: all libgit test install uninstall clean force-version get-git \ |
| 104 | doc man-doc html-doc clean-doc | ||
| 104 | 105 | ||
| 105 | all: cgit | 106 | all: cgit |
| 106 | 107 | ||
| @@ -149,8 +150,22 @@ uninstall: | |||
| 149 | rm -f $(CGIT_DATA_PATH)/cgit.css | 150 | rm -f $(CGIT_DATA_PATH)/cgit.css |
| 150 | rm -f $(CGIT_DATA_PATH)/cgit.png | 151 | rm -f $(CGIT_DATA_PATH)/cgit.png |
| 151 | 152 | ||
| 152 | clean: | 153 | doc: man-doc html-doc pdf-doc |
| 154 | |||
| 155 | man-doc: cgitrc.5.txt | ||
| 156 | a2x -f manpage cgitrc.5.txt | ||
| 157 | |||
| 158 | html-doc: cgitrc.5.txt | ||
| 159 | a2x -f xhtml --stylesheet=cgit-doc.css cgitrc.5.txt | ||
| 160 | |||
| 161 | pdf-doc: cgitrc.5.txt | ||
| 162 | a2x -f pdf cgitrc.5.txt | ||
| 163 | |||
| 164 | clean: clean-doc | ||
| 153 | rm -f cgit VERSION *.o *.d | 165 | rm -f cgit VERSION *.o *.d |
| 154 | 166 | ||
| 167 | clean-doc: | ||
| 168 | rm -f cgitrc.5 cgitrc.5.html cgitrc.5.pdf cgitrc.5.xml cgitrc.5.fo | ||
| 169 | |||
| 155 | get-git: | 170 | get-git: |
| 156 | curl $(GIT_URL) | tar -xj && rm -rf git && mv git-$(GIT_VER) git | 171 | curl $(GIT_URL) | tar -xj && rm -rf git && mv git-$(GIT_VER) git |
| @@ -32,4 +32,6 @@ extern int cache_ls(const char *path); | |||
| 32 | /* Print a message to stdout */ | 32 | /* Print a message to stdout */ |
| 33 | extern void cache_log(const char *format, ...); | 33 | extern void cache_log(const char *format, ...); |
| 34 | 34 | ||
| 35 | extern unsigned long hash_str(const char *str); | ||
| 36 | |||
| 35 | #endif /* CGIT_CACHE_H */ | 37 | #endif /* CGIT_CACHE_H */ |
diff --git a/cgit-doc.css b/cgit-doc.css new file mode 100644 index 0000000..5a399b6 --- /dev/null +++ b/cgit-doc.css | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | div.variablelist dt { | ||
| 2 | margin-top: 1em; | ||
| 3 | } | ||
| @@ -17,9 +17,81 @@ | |||
| 17 | 17 | ||
| 18 | const char *cgit_version = CGIT_VERSION; | 18 | const char *cgit_version = CGIT_VERSION; |
| 19 | 19 | ||
| 20 | void add_mimetype(const char *name, const char *value) | ||
| 21 | { | ||
| 22 | struct string_list_item *item; | ||
| 23 | |||
| 24 | item = string_list_insert(xstrdup(name), &ctx.cfg.mimetypes); | ||
| 25 | item->util = xstrdup(value); | ||
| 26 | } | ||
| 27 | |||
| 28 | struct cgit_filter *new_filter(const char *cmd, int extra_args) | ||
| 29 | { | ||
| 30 | struct cgit_filter *f; | ||
| 31 | |||
| 32 | if (!cmd || !cmd[0]) | ||
| 33 | return NULL; | ||
| 34 | |||
| 35 | f = xmalloc(sizeof(struct cgit_filter)); | ||
| 36 | f->cmd = xstrdup(cmd); | ||
| 37 | f->argv = xmalloc((2 + extra_args) * sizeof(char *)); | ||
| 38 | f->argv[0] = f->cmd; | ||
| 39 | f->argv[1] = NULL; | ||
| 40 | return f; | ||
| 41 | } | ||
| 42 | |||
| 43 | static void process_cached_repolist(const char *path); | ||
| 44 | |||
| 45 | void repo_config(struct cgit_repo *repo, const char *name, const char *value) | ||
| 46 | { | ||
| 47 | if (!strcmp(name, "name")) | ||
| 48 | repo->name = xstrdup(value); | ||
| 49 | else if (!strcmp(name, "clone-url")) | ||
| 50 | repo->clone_url = xstrdup(value); | ||
| 51 | else if (!strcmp(name, "desc")) | ||
| 52 | repo->desc = xstrdup(value); | ||
| 53 | else if (!strcmp(name, "owner")) | ||
| 54 | repo->owner = xstrdup(value); | ||
| 55 | else if (!strcmp(name, "defbranch")) | ||
| 56 | repo->defbranch = xstrdup(value); | ||
| 57 | else if (!strcmp(name, "snapshots")) | ||
| 58 | repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); | ||
| 59 | else if (!strcmp(name, "enable-log-filecount")) | ||
| 60 | repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); | ||
| 61 | else if (!strcmp(name, "enable-log-linecount")) | ||
| 62 | repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); | ||
| 63 | else if (!strcmp(name, "max-stats")) | ||
| 64 | repo->max_stats = cgit_find_stats_period(value, NULL); | ||
| 65 | else if (!strcmp(name, "module-link")) | ||
| 66 | repo->module_link= xstrdup(value); | ||
| 67 | else if (!strcmp(name, "section")) | ||
| 68 | repo->section = xstrdup(value); | ||
| 69 | else if (!strcmp(name, "readme") && value != NULL) { | ||
| 70 | if (*value == '/') | ||
| 71 | ctx.repo->readme = xstrdup(value); | ||
| 72 | else | ||
| 73 | ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, value)); | ||
| 74 | } else if (ctx.cfg.enable_filter_overrides) { | ||
| 75 | if (!strcmp(name, "about-filter")) | ||
| 76 | repo->about_filter = new_filter(value, 0); | ||
| 77 | else if (!strcmp(name, "commit-filter")) | ||
| 78 | repo->commit_filter = new_filter(value, 0); | ||
| 79 | else if (!strcmp(name, "source-filter")) | ||
| 80 | repo->source_filter = new_filter(value, 1); | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 20 | void config_cb(const char *name, const char *value) | 84 | void config_cb(const char *name, const char *value) |
| 21 | { | 85 | { |
| 22 | if (!strcmp(name, "root-title")) | 86 | if (!strcmp(name, "section") || !strcmp(name, "repo.group")) |
| 87 | ctx.cfg.section = xstrdup(value); | ||
| 88 | else if (!strcmp(name, "repo.url")) | ||
| 89 | ctx.repo = cgit_add_repo(value); | ||
| 90 | else if (ctx.repo && !strcmp(name, "repo.path")) | ||
| 91 | ctx.repo->path = trim_end(value, '/'); | ||
| 92 | else if (ctx.repo && !prefixcmp(name, "repo.")) | ||
| 93 | repo_config(ctx.repo, name + 5, value); | ||
| 94 | else if (!strcmp(name, "root-title")) | ||
| 23 | ctx.cfg.root_title = xstrdup(value); | 95 | ctx.cfg.root_title = xstrdup(value); |
| 24 | else if (!strcmp(name, "root-desc")) | 96 | else if (!strcmp(name, "root-desc")) |
| 25 | ctx.cfg.root_desc = xstrdup(value); | 97 | ctx.cfg.root_desc = xstrdup(value); |
| @@ -31,6 +103,8 @@ void config_cb(const char *name, const char *value) | |||
| 31 | ctx.cfg.favicon = xstrdup(value); | 103 | ctx.cfg.favicon = xstrdup(value); |
| 32 | else if (!strcmp(name, "footer")) | 104 | else if (!strcmp(name, "footer")) |
| 33 | ctx.cfg.footer = xstrdup(value); | 105 | ctx.cfg.footer = xstrdup(value); |
| 106 | else if (!strcmp(name, "head-include")) | ||
| 107 | ctx.cfg.head_include = xstrdup(value); | ||
| 34 | else if (!strcmp(name, "header")) | 108 | else if (!strcmp(name, "header")) |
| 35 | ctx.cfg.header = xstrdup(value); | 109 | ctx.cfg.header = xstrdup(value); |
| 36 | else if (!strcmp(name, "logo")) | 110 | else if (!strcmp(name, "logo")) |
| @@ -49,14 +123,22 @@ void config_cb(const char *name, const char *value) | |||
| 49 | ctx.cfg.virtual_root = ""; | 123 | ctx.cfg.virtual_root = ""; |
| 50 | } else if (!strcmp(name, "nocache")) | 124 | } else if (!strcmp(name, "nocache")) |
| 51 | ctx.cfg.nocache = atoi(value); | 125 | ctx.cfg.nocache = atoi(value); |
| 126 | else if (!strcmp(name, "noplainemail")) | ||
| 127 | ctx.cfg.noplainemail = atoi(value); | ||
| 128 | else if (!strcmp(name, "noheader")) | ||
| 129 | ctx.cfg.noheader = atoi(value); | ||
| 52 | else if (!strcmp(name, "snapshots")) | 130 | else if (!strcmp(name, "snapshots")) |
| 53 | ctx.cfg.snapshots = cgit_parse_snapshots_mask(value); | 131 | ctx.cfg.snapshots = cgit_parse_snapshots_mask(value); |
| 132 | else if (!strcmp(name, "enable-filter-overrides")) | ||
| 133 | ctx.cfg.enable_filter_overrides = atoi(value); | ||
| 54 | else if (!strcmp(name, "enable-index-links")) | 134 | else if (!strcmp(name, "enable-index-links")) |
| 55 | ctx.cfg.enable_index_links = atoi(value); | 135 | ctx.cfg.enable_index_links = atoi(value); |
| 56 | else if (!strcmp(name, "enable-log-filecount")) | 136 | else if (!strcmp(name, "enable-log-filecount")) |
| 57 | ctx.cfg.enable_log_filecount = atoi(value); | 137 | ctx.cfg.enable_log_filecount = atoi(value); |
| 58 | else if (!strcmp(name, "enable-log-linecount")) | 138 | else if (!strcmp(name, "enable-log-linecount")) |
| 59 | ctx.cfg.enable_log_linecount = atoi(value); | 139 | ctx.cfg.enable_log_linecount = atoi(value); |
| 140 | else if (!strcmp(name, "enable-tree-linenumbers")) | ||
| 141 | ctx.cfg.enable_tree_linenumbers = atoi(value); | ||
| 60 | else if (!strcmp(name, "max-stats")) | 142 | else if (!strcmp(name, "max-stats")) |
| 61 | ctx.cfg.max_stats = cgit_find_stats_period(value, NULL); | 143 | ctx.cfg.max_stats = cgit_find_stats_period(value, NULL); |
| 62 | else if (!strcmp(name, "cache-size")) | 144 | else if (!strcmp(name, "cache-size")) |
| @@ -67,10 +149,18 @@ void config_cb(const char *name, const char *value) | |||
| 67 | ctx.cfg.cache_root_ttl = atoi(value); | 149 | ctx.cfg.cache_root_ttl = atoi(value); |
| 68 | else if (!strcmp(name, "cache-repo-ttl")) | 150 | else if (!strcmp(name, "cache-repo-ttl")) |
| 69 | ctx.cfg.cache_repo_ttl = atoi(value); | 151 | ctx.cfg.cache_repo_ttl = atoi(value); |
| 152 | else if (!strcmp(name, "cache-scanrc-ttl")) | ||
| 153 | ctx.cfg.cache_scanrc_ttl = atoi(value); | ||
| 70 | else if (!strcmp(name, "cache-static-ttl")) | 154 | else if (!strcmp(name, "cache-static-ttl")) |
| 71 | ctx.cfg.cache_static_ttl = atoi(value); | 155 | ctx.cfg.cache_static_ttl = atoi(value); |
| 72 | else if (!strcmp(name, "cache-dynamic-ttl")) | 156 | else if (!strcmp(name, "cache-dynamic-ttl")) |
| 73 | ctx.cfg.cache_dynamic_ttl = atoi(value); | 157 | ctx.cfg.cache_dynamic_ttl = atoi(value); |
| 158 | else if (!strcmp(name, "about-filter")) | ||
| 159 | ctx.cfg.about_filter = new_filter(value, 0); | ||
| 160 | else if (!strcmp(name, "commit-filter")) | ||
| 161 | ctx.cfg.commit_filter = new_filter(value, 0); | ||
| 162 | else if (!strcmp(name, "embedded")) | ||
| 163 | ctx.cfg.embedded = atoi(value); | ||
| 74 | else if (!strcmp(name, "max-message-length")) | 164 | else if (!strcmp(name, "max-message-length")) |
| 75 | ctx.cfg.max_msg_len = atoi(value); | 165 | ctx.cfg.max_msg_len = atoi(value); |
| 76 | else if (!strcmp(name, "max-repodesc-length")) | 166 | else if (!strcmp(name, "max-repodesc-length")) |
| @@ -79,6 +169,13 @@ void config_cb(const char *name, const char *value) | |||
| 79 | ctx.cfg.max_repo_count = atoi(value); | 169 | ctx.cfg.max_repo_count = atoi(value); |
| 80 | else if (!strcmp(name, "max-commit-count")) | 170 | else if (!strcmp(name, "max-commit-count")) |
| 81 | ctx.cfg.max_commit_count = atoi(value); | 171 | ctx.cfg.max_commit_count = atoi(value); |
| 172 | else if (!strcmp(name, "scan-path")) | ||
| 173 | if (!ctx.cfg.nocache && ctx.cfg.cache_size) | ||
| 174 | process_cached_repolist(value); | ||
| 175 | else | ||
| 176 | scan_tree(value, repo_config); | ||
| 177 | else if (!strcmp(name, "source-filter")) | ||
| 178 | ctx.cfg.source_filter = new_filter(value, 1); | ||
| 82 | else if (!strcmp(name, "summary-log")) | 179 | else if (!strcmp(name, "summary-log")) |
| 83 | ctx.cfg.summary_log = atoi(value); | 180 | ctx.cfg.summary_log = atoi(value); |
| 84 | else if (!strcmp(name, "summary-branches")) | 181 | else if (!strcmp(name, "summary-branches")) |
| @@ -95,38 +192,9 @@ void config_cb(const char *name, const char *value) | |||
| 95 | ctx.cfg.clone_prefix = xstrdup(value); | 192 | ctx.cfg.clone_prefix = xstrdup(value); |
| 96 | else if (!strcmp(name, "local-time")) | 193 | else if (!strcmp(name, "local-time")) |
| 97 | ctx.cfg.local_time = atoi(value); | 194 | ctx.cfg.local_time = atoi(value); |
| 98 | else if (!strcmp(name, "repo.group")) | 195 | else if (!prefixcmp(name, "mimetype.")) |
| 99 | ctx.cfg.repo_group = xstrdup(value); | 196 | add_mimetype(name + 9, value); |
| 100 | else if (!strcmp(name, "repo.url")) | 197 | else if (!strcmp(name, "include")) |
| 101 | ctx.repo = cgit_add_repo(value); | ||
| 102 | else if (!strcmp(name, "repo.name")) | ||
| 103 | ctx.repo->name = xstrdup(value); | ||
| 104 | else if (ctx.repo && !strcmp(name, "repo.path")) | ||
| 105 | ctx.repo->path = trim_end(value, '/'); | ||
| 106 | else if (ctx.repo && !strcmp(name, "repo.clone-url")) | ||
| 107 | ctx.repo->clone_url = xstrdup(value); | ||
| 108 | else if (ctx.repo && !strcmp(name, "repo.desc")) | ||
| 109 | ctx.repo->desc = xstrdup(value); | ||
| 110 | else if (ctx.repo && !strcmp(name, "repo.owner")) | ||
| 111 | ctx.repo->owner = xstrdup(value); | ||
| 112 | else if (ctx.repo && !strcmp(name, "repo.defbranch")) | ||
| 113 | ctx.repo->defbranch = xstrdup(value); | ||
| 114 | else if (ctx.repo && !strcmp(name, "repo.snapshots")) | ||
| 115 | ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */ | ||
| 116 | else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount")) | ||
| 117 | ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); | ||
| 118 | else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount")) | ||
| 119 | ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); | ||
| 120 | else if (ctx.repo && !strcmp(name, "repo.max-stats")) | ||
| 121 | ctx.repo->max_stats = cgit_find_stats_period(value, NULL); | ||
| 122 | else if (ctx.repo && !strcmp(name, "repo.module-link")) | ||
| 123 | ctx.repo->module_link= xstrdup(value); | ||
| 124 | else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) { | ||
| 125 | if (*value == '/') | ||
| 126 | ctx.repo->readme = xstrdup(value); | ||
| 127 | else | ||
| 128 | ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, value)); | ||
| 129 | } else if (!strcmp(name, "include")) | ||
| 130 | parse_configfile(value, config_cb); | 198 | parse_configfile(value, config_cb); |
| 131 | } | 199 | } |
| 132 | 200 | ||
| @@ -173,6 +241,11 @@ static void querystring_cb(const char *name, const char *value) | |||
| 173 | } | 241 | } |
| 174 | } | 242 | } |
| 175 | 243 | ||
| 244 | char *xstrdupn(const char *str) | ||
| 245 | { | ||
| 246 | return (str ? xstrdup(str) : NULL); | ||
| 247 | } | ||
| 248 | |||
| 176 | static void prepare_context(struct cgit_context *ctx) | 249 | static void prepare_context(struct cgit_context *ctx) |
| 177 | { | 250 | { |
| 178 | memset(ctx, 0, sizeof(ctx)); | 251 | memset(ctx, 0, sizeof(ctx)); |
| @@ -184,10 +257,12 @@ static void prepare_context(struct cgit_context *ctx) | |||
| 184 | ctx->cfg.cache_repo_ttl = 5; | 257 | ctx->cfg.cache_repo_ttl = 5; |
| 185 | ctx->cfg.cache_root = CGIT_CACHE_ROOT; | 258 | ctx->cfg.cache_root = CGIT_CACHE_ROOT; |
| 186 | ctx->cfg.cache_root_ttl = 5; | 259 | ctx->cfg.cache_root_ttl = 5; |
| 260 | ctx->cfg.cache_scanrc_ttl = 15; | ||
| 187 | ctx->cfg.cache_static_ttl = -1; | 261 | ctx->cfg.cache_static_ttl = -1; |
| 188 | ctx->cfg.css = "/cgit.css"; | 262 | ctx->cfg.css = "/cgit.css"; |
| 189 | ctx->cfg.logo = "/git-logo.png"; | 263 | ctx->cfg.logo = "/cgit.png"; |
| 190 | ctx->cfg.local_time = 0; | 264 | ctx->cfg.local_time = 0; |
| 265 | ctx->cfg.enable_tree_linenumbers = 1; | ||
| 191 | ctx->cfg.max_repo_count = 50; | 266 | ctx->cfg.max_repo_count = 50; |
| 192 | ctx->cfg.max_commit_count = 50; | 267 | ctx->cfg.max_commit_count = 50; |
| 193 | ctx->cfg.max_lock_attempts = 5; | 268 | ctx->cfg.max_lock_attempts = 5; |
| @@ -200,15 +275,34 @@ static void prepare_context(struct cgit_context *ctx) | |||
| 200 | ctx->cfg.root_title = "Git repository browser"; | 275 | ctx->cfg.root_title = "Git repository browser"; |
| 201 | ctx->cfg.root_desc = "a fast webinterface for the git dscm"; | 276 | ctx->cfg.root_desc = "a fast webinterface for the git dscm"; |
| 202 | ctx->cfg.script_name = CGIT_SCRIPT_NAME; | 277 | ctx->cfg.script_name = CGIT_SCRIPT_NAME; |
| 278 | ctx->cfg.section = ""; | ||
| 203 | ctx->cfg.summary_branches = 10; | 279 | ctx->cfg.summary_branches = 10; |
| 204 | ctx->cfg.summary_log = 10; | 280 | ctx->cfg.summary_log = 10; |
| 205 | ctx->cfg.summary_tags = 10; | 281 | ctx->cfg.summary_tags = 10; |
| 282 | ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG")); | ||
| 283 | ctx->env.http_host = xstrdupn(getenv("HTTP_HOST")); | ||
| 284 | ctx->env.https = xstrdupn(getenv("HTTPS")); | ||
| 285 | ctx->env.no_http = xstrdupn(getenv("NO_HTTP")); | ||
| 286 | ctx->env.path_info = xstrdupn(getenv("PATH_INFO")); | ||
| 287 | ctx->env.query_string = xstrdupn(getenv("QUERY_STRING")); | ||
| 288 | ctx->env.request_method = xstrdupn(getenv("REQUEST_METHOD")); | ||
| 289 | ctx->env.script_name = xstrdupn(getenv("SCRIPT_NAME")); | ||
| 290 | ctx->env.server_name = xstrdupn(getenv("SERVER_NAME")); | ||
| 291 | ctx->env.server_port = xstrdupn(getenv("SERVER_PORT")); | ||
| 206 | ctx->page.mimetype = "text/html"; | 292 | ctx->page.mimetype = "text/html"; |
| 207 | ctx->page.charset = PAGE_ENCODING; | 293 | ctx->page.charset = PAGE_ENCODING; |
| 208 | ctx->page.filename = NULL; | 294 | ctx->page.filename = NULL; |
| 209 | ctx->page.size = 0; | 295 | ctx->page.size = 0; |
| 210 | ctx->page.modified = time(NULL); | 296 | ctx->page.modified = time(NULL); |
| 211 | ctx->page.expires = ctx->page.modified; | 297 | ctx->page.expires = ctx->page.modified; |
| 298 | ctx->page.etag = NULL; | ||
| 299 | memset(&ctx->cfg.mimetypes, 0, sizeof(struct string_list)); | ||
| 300 | if (ctx->env.script_name) | ||
| 301 | ctx->cfg.script_name = ctx->env.script_name; | ||
| 302 | if (ctx->env.query_string) | ||
| 303 | ctx->qry.raw = ctx->env.query_string; | ||
| 304 | if (!ctx->env.cgit_config) | ||
| 305 | ctx->env.cgit_config = CGIT_CONFIG; | ||
| 212 | } | 306 | } |
| 213 | 307 | ||
| 214 | struct refmatch { | 308 | struct refmatch { |
| @@ -288,6 +382,8 @@ static int prepare_repo_cmd(struct cgit_context *ctx) | |||
| 288 | if (get_sha1(ctx->qry.head, sha1)) { | 382 | if (get_sha1(ctx->qry.head, sha1)) { |
| 289 | tmp = xstrdup(ctx->qry.head); | 383 | tmp = xstrdup(ctx->qry.head); |
| 290 | ctx->qry.head = ctx->repo->defbranch; | 384 | ctx->qry.head = ctx->repo->defbranch; |
| 385 | ctx->page.status = 404; | ||
| 386 | ctx->page.statusmsg = "not found"; | ||
| 291 | cgit_print_http_headers(ctx); | 387 | cgit_print_http_headers(ctx); |
| 292 | cgit_print_docstart(ctx); | 388 | cgit_print_docstart(ctx); |
| 293 | cgit_print_pageheader(ctx); | 389 | cgit_print_pageheader(ctx); |
| @@ -344,28 +440,151 @@ int cmp_repos(const void *a, const void *b) | |||
| 344 | return strcmp(ra->url, rb->url); | 440 | return strcmp(ra->url, rb->url); |
| 345 | } | 441 | } |
| 346 | 442 | ||
| 347 | void print_repo(struct cgit_repo *repo) | 443 | char *build_snapshot_setting(int bitmap) |
| 348 | { | 444 | { |
| 349 | printf("repo.url=%s\n", repo->url); | 445 | const struct cgit_snapshot_format *f; |
| 350 | printf("repo.name=%s\n", repo->name); | 446 | char *result = xstrdup(""); |
| 351 | printf("repo.path=%s\n", repo->path); | 447 | char *tmp; |
| 448 | int len; | ||
| 449 | |||
| 450 | for (f = cgit_snapshot_formats; f->suffix; f++) { | ||
| 451 | if (f->bit & bitmap) { | ||
| 452 | tmp = result; | ||
| 453 | result = xstrdup(fmt("%s%s ", tmp, f->suffix)); | ||
| 454 | free(tmp); | ||
| 455 | } | ||
| 456 | } | ||
| 457 | len = strlen(result); | ||
| 458 | if (len) | ||
| 459 | result[len - 1] = '\0'; | ||
| 460 | return result; | ||
| 461 | } | ||
| 462 | |||
| 463 | char *get_first_line(char *txt) | ||
| 464 | { | ||
| 465 | char *t = xstrdup(txt); | ||
| 466 | char *p = strchr(t, '\n'); | ||
| 467 | if (p) | ||
| 468 | *p = '\0'; | ||
| 469 | return t; | ||
| 470 | } | ||
| 471 | |||
| 472 | void print_repo(FILE *f, struct cgit_repo *repo) | ||
| 473 | { | ||
| 474 | fprintf(f, "repo.url=%s\n", repo->url); | ||
| 475 | fprintf(f, "repo.name=%s\n", repo->name); | ||
| 476 | fprintf(f, "repo.path=%s\n", repo->path); | ||
| 352 | if (repo->owner) | 477 | if (repo->owner) |
| 353 | printf("repo.owner=%s\n", repo->owner); | 478 | fprintf(f, "repo.owner=%s\n", repo->owner); |
| 354 | if (repo->desc) | 479 | if (repo->desc) { |
| 355 | printf("repo.desc=%s\n", repo->desc); | 480 | char *tmp = get_first_line(repo->desc); |
| 481 | fprintf(f, "repo.desc=%s\n", tmp); | ||
| 482 | free(tmp); | ||
| 483 | } | ||
| 356 | if (repo->readme) | 484 | if (repo->readme) |
| 357 | printf("repo.readme=%s\n", repo->readme); | 485 | fprintf(f, "repo.readme=%s\n", repo->readme); |
| 358 | printf("\n"); | 486 | if (repo->defbranch) |
| 487 | fprintf(f, "repo.defbranch=%s\n", repo->defbranch); | ||
| 488 | if (repo->module_link) | ||
| 489 | fprintf(f, "repo.module-link=%s\n", repo->module_link); | ||
| 490 | if (repo->section) | ||
| 491 | fprintf(f, "repo.section=%s\n", repo->section); | ||
| 492 | if (repo->clone_url) | ||
| 493 | fprintf(f, "repo.clone-url=%s\n", repo->clone_url); | ||
| 494 | fprintf(f, "repo.enable-log-filecount=%d\n", | ||
| 495 | repo->enable_log_filecount); | ||
| 496 | fprintf(f, "repo.enable-log-linecount=%d\n", | ||
| 497 | repo->enable_log_linecount); | ||
| 498 | if (repo->about_filter && repo->about_filter != ctx.cfg.about_filter) | ||
| 499 | fprintf(f, "repo.about-filter=%s\n", repo->about_filter->cmd); | ||
| 500 | if (repo->commit_filter && repo->commit_filter != ctx.cfg.commit_filter) | ||
| 501 | fprintf(f, "repo.commit-filter=%s\n", repo->commit_filter->cmd); | ||
| 502 | if (repo->source_filter && repo->source_filter != ctx.cfg.source_filter) | ||
| 503 | fprintf(f, "repo.source-filter=%s\n", repo->source_filter->cmd); | ||
| 504 | if (repo->snapshots != ctx.cfg.snapshots) { | ||
| 505 | char *tmp = build_snapshot_setting(repo->snapshots); | ||
| 506 | fprintf(f, "repo.snapshots=%s\n", tmp); | ||
| 507 | free(tmp); | ||
| 508 | } | ||
| 509 | if (repo->max_stats != ctx.cfg.max_stats) | ||
| 510 | fprintf(f, "repo.max-stats=%s\n", | ||
| 511 | cgit_find_stats_periodname(repo->max_stats)); | ||
| 512 | fprintf(f, "\n"); | ||
| 359 | } | 513 | } |
| 360 | 514 | ||
| 361 | void print_repolist(struct cgit_repolist *list) | 515 | void print_repolist(FILE *f, struct cgit_repolist *list, int start) |
| 362 | { | 516 | { |
| 363 | int i; | 517 | int i; |
| 364 | 518 | ||
| 365 | for(i = 0; i < list->count; i++) | 519 | for(i = start; i < list->count; i++) |
| 366 | print_repo(&list->repos[i]); | 520 | print_repo(f, &list->repos[i]); |
| 521 | } | ||
| 522 | |||
| 523 | /* Scan 'path' for git repositories, save the resulting repolist in 'cached_rc' | ||
| 524 | * and return 0 on success. | ||
| 525 | */ | ||
| 526 | static int generate_cached_repolist(const char *path, const char *cached_rc) | ||
