summaryrefslogtreecommitdiffabout
path: root/cgit.c
authorLars Hjemli <hjemli@gmail.com>2009-07-31 14:55:27 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2009-07-31 15:41:21 (UTC)
commit46b7abed99e957008c01c02cf612aa526ba92f04 (patch) (unidiff)
tree2cdbfe5281c2ffa645def488d53db0a8b82842f4 /cgit.c
parent18dfbdc099c1398016427b6fa7f1a1facb363998 (diff)
downloadcgit-46b7abed99e957008c01c02cf612aa526ba92f04.zip
cgit-46b7abed99e957008c01c02cf612aa526ba92f04.tar.gz
cgit-46b7abed99e957008c01c02cf612aa526ba92f04.tar.bz2
ui-tree: add support for source-filter option
This new option is used to specify an external command which will be executed when displaying blob content in the tree view. Blob content will be written to STDIN of the filter and STDOUT from the filter will be included verbatim in the html output from cgit. The file name of the blob will be passed as the only argument to the filter command. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'cgit.c') (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/cgit.c b/cgit.c
index 779a464..eb7b45d 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,230 +1,232 @@
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 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include "cgit.h" 9#include "cgit.h"
10#include "cache.h" 10#include "cache.h"
11#include "cmd.h" 11#include "cmd.h"
12#include "configfile.h" 12#include "configfile.h"
13#include "html.h" 13#include "html.h"
14#include "ui-shared.h" 14#include "ui-shared.h"
15#include "ui-stats.h" 15#include "ui-stats.h"
16#include "scan-tree.h" 16#include "scan-tree.h"
17 17
18const char *cgit_version = CGIT_VERSION; 18const char *cgit_version = CGIT_VERSION;
19 19
20struct cgit_filter *new_filter(const char *cmd, int extra_args) 20struct cgit_filter *new_filter(const char *cmd, int extra_args)
21{ 21{
22 struct cgit_filter *f; 22 struct cgit_filter *f;
23 23
24 if (!cmd) 24 if (!cmd)
25 return NULL; 25 return NULL;
26 26
27 f = xmalloc(sizeof(struct cgit_filter)); 27 f = xmalloc(sizeof(struct cgit_filter));
28 f->cmd = xstrdup(cmd); 28 f->cmd = xstrdup(cmd);
29 f->argv = xmalloc((2 + extra_args) * sizeof(char *)); 29 f->argv = xmalloc((2 + extra_args) * sizeof(char *));
30 f->argv[0] = f->cmd; 30 f->argv[0] = f->cmd;
31 f->argv[1] = NULL; 31 f->argv[1] = NULL;
32 return f; 32 return f;
33} 33}
34 34
35void config_cb(const char *name, const char *value) 35void config_cb(const char *name, const char *value)
36{ 36{
37 if (!strcmp(name, "root-title")) 37 if (!strcmp(name, "root-title"))
38 ctx.cfg.root_title = xstrdup(value); 38 ctx.cfg.root_title = xstrdup(value);
39 else if (!strcmp(name, "root-desc")) 39 else if (!strcmp(name, "root-desc"))
40 ctx.cfg.root_desc = xstrdup(value); 40 ctx.cfg.root_desc = xstrdup(value);
41 else if (!strcmp(name, "root-readme")) 41 else if (!strcmp(name, "root-readme"))
42 ctx.cfg.root_readme = xstrdup(value); 42 ctx.cfg.root_readme = xstrdup(value);
43 else if (!strcmp(name, "css")) 43 else if (!strcmp(name, "css"))
44 ctx.cfg.css = xstrdup(value); 44 ctx.cfg.css = xstrdup(value);
45 else if (!strcmp(name, "favicon")) 45 else if (!strcmp(name, "favicon"))
46 ctx.cfg.favicon = xstrdup(value); 46 ctx.cfg.favicon = xstrdup(value);
47 else if (!strcmp(name, "footer")) 47 else if (!strcmp(name, "footer"))
48 ctx.cfg.footer = xstrdup(value); 48 ctx.cfg.footer = xstrdup(value);
49 else if (!strcmp(name, "head-include")) 49 else if (!strcmp(name, "head-include"))
50 ctx.cfg.head_include = xstrdup(value); 50 ctx.cfg.head_include = xstrdup(value);
51 else if (!strcmp(name, "header")) 51 else if (!strcmp(name, "header"))
52 ctx.cfg.header = xstrdup(value); 52 ctx.cfg.header = xstrdup(value);
53 else if (!strcmp(name, "logo")) 53 else if (!strcmp(name, "logo"))
54 ctx.cfg.logo = xstrdup(value); 54 ctx.cfg.logo = xstrdup(value);
55 else if (!strcmp(name, "index-header")) 55 else if (!strcmp(name, "index-header"))
56 ctx.cfg.index_header = xstrdup(value); 56 ctx.cfg.index_header = xstrdup(value);
57 else if (!strcmp(name, "index-info")) 57 else if (!strcmp(name, "index-info"))
58 ctx.cfg.index_info = xstrdup(value); 58 ctx.cfg.index_info = xstrdup(value);
59 else if (!strcmp(name, "logo-link")) 59 else if (!strcmp(name, "logo-link"))
60 ctx.cfg.logo_link = xstrdup(value); 60 ctx.cfg.logo_link = xstrdup(value);
61 else if (!strcmp(name, "module-link")) 61 else if (!strcmp(name, "module-link"))
62 ctx.cfg.module_link = xstrdup(value); 62 ctx.cfg.module_link = xstrdup(value);
63 else if (!strcmp(name, "virtual-root")) { 63 else if (!strcmp(name, "virtual-root")) {
64 ctx.cfg.virtual_root = trim_end(value, '/'); 64 ctx.cfg.virtual_root = trim_end(value, '/');
65 if (!ctx.cfg.virtual_root && (!strcmp(value, "/"))) 65 if (!ctx.cfg.virtual_root && (!strcmp(value, "/")))
66 ctx.cfg.virtual_root = ""; 66 ctx.cfg.virtual_root = "";
67 } else if (!strcmp(name, "nocache")) 67 } else if (!strcmp(name, "nocache"))
68 ctx.cfg.nocache = atoi(value); 68 ctx.cfg.nocache = atoi(value);
69 else if (!strcmp(name, "noheader")) 69 else if (!strcmp(name, "noheader"))
70 ctx.cfg.noheader = atoi(value); 70 ctx.cfg.noheader = atoi(value);
71 else if (!strcmp(name, "snapshots")) 71 else if (!strcmp(name, "snapshots"))
72 ctx.cfg.snapshots = cgit_parse_snapshots_mask(value); 72 ctx.cfg.snapshots = cgit_parse_snapshots_mask(value);
73 else if (!strcmp(name, "enable-index-links")) 73 else if (!strcmp(name, "enable-index-links"))
74 ctx.cfg.enable_index_links = atoi(value); 74 ctx.cfg.enable_index_links = atoi(value);
75 else if (!strcmp(name, "enable-log-filecount")) 75 else if (!strcmp(name, "enable-log-filecount"))
76 ctx.cfg.enable_log_filecount = atoi(value); 76 ctx.cfg.enable_log_filecount = atoi(value);
77 else if (!strcmp(name, "enable-log-linecount")) 77 else if (!strcmp(name, "enable-log-linecount"))
78 ctx.cfg.enable_log_linecount = atoi(value); 78 ctx.cfg.enable_log_linecount = atoi(value);
79 else if (!strcmp(name, "max-stats")) 79 else if (!strcmp(name, "max-stats"))
80 ctx.cfg.max_stats = cgit_find_stats_period(value, NULL); 80 ctx.cfg.max_stats = cgit_find_stats_period(value, NULL);
81 else if (!strcmp(name, "cache-size")) 81 else if (!strcmp(name, "cache-size"))
82 ctx.cfg.cache_size = atoi(value); 82 ctx.cfg.cache_size = atoi(value);
83 else if (!strcmp(name, "cache-root")) 83 else if (!strcmp(name, "cache-root"))
84 ctx.cfg.cache_root = xstrdup(value); 84 ctx.cfg.cache_root = xstrdup(value);
85 else if (!strcmp(name, "cache-root-ttl")) 85 else if (!strcmp(name, "cache-root-ttl"))
86 ctx.cfg.cache_root_ttl = atoi(value); 86 ctx.cfg.cache_root_ttl = atoi(value);
87 else if (!strcmp(name, "cache-repo-ttl")) 87 else if (!strcmp(name, "cache-repo-ttl"))
88 ctx.cfg.cache_repo_ttl = atoi(value); 88 ctx.cfg.cache_repo_ttl = atoi(value);
89 else if (!strcmp(name, "cache-static-ttl")) 89 else if (!strcmp(name, "cache-static-ttl"))
90 ctx.cfg.cache_static_ttl = atoi(value); 90 ctx.cfg.cache_static_ttl = atoi(value);
91 else if (!strcmp(name, "cache-dynamic-ttl")) 91 else if (!strcmp(name, "cache-dynamic-ttl"))
92 ctx.cfg.cache_dynamic_ttl = atoi(value); 92 ctx.cfg.cache_dynamic_ttl = atoi(value);
93 else if (!strcmp(name, "embedded")) 93 else if (!strcmp(name, "embedded"))
94 ctx.cfg.embedded = atoi(value); 94 ctx.cfg.embedded = atoi(value);
95 else if (!strcmp(name, "max-message-length")) 95 else if (!strcmp(name, "max-message-length"))
96 ctx.cfg.max_msg_len = atoi(value); 96 ctx.cfg.max_msg_len = atoi(value);
97 else if (!strcmp(name, "max-repodesc-length")) 97 else if (!strcmp(name, "max-repodesc-length"))
98 ctx.cfg.max_repodesc_len = atoi(value); 98 ctx.cfg.max_repodesc_len = atoi(value);
99 else if (!strcmp(name, "max-repo-count")) 99 else if (!strcmp(name, "max-repo-count"))
100 ctx.cfg.max_repo_count = atoi(value); 100 ctx.cfg.max_repo_count = atoi(value);
101 else if (!strcmp(name, "max-commit-count")) 101 else if (!strcmp(name, "max-commit-count"))
102 ctx.cfg.max_commit_count = atoi(value); 102 ctx.cfg.max_commit_count = atoi(value);
103 else if (!strcmp(name, "source-filter"))
104 ctx.cfg.source_filter = new_filter(value, 1);
103 else if (!strcmp(name, "summary-log")) 105 else if (!strcmp(name, "summary-log"))
104 ctx.cfg.summary_log = atoi(value); 106 ctx.cfg.summary_log = atoi(value);
105 else if (!strcmp(name, "summary-branches")) 107 else if (!strcmp(name, "summary-branches"))
106 ctx.cfg.summary_branches = atoi(value); 108 ctx.cfg.summary_branches = atoi(value);
107 else if (!strcmp(name, "summary-tags")) 109 else if (!strcmp(name, "summary-tags"))
108 ctx.cfg.summary_tags = atoi(value); 110 ctx.cfg.summary_tags = atoi(value);
109 else if (!strcmp(name, "agefile")) 111 else if (!strcmp(name, "agefile"))
110 ctx.cfg.agefile = xstrdup(value); 112 ctx.cfg.agefile = xstrdup(value);
111 else if (!strcmp(name, "renamelimit")) 113 else if (!strcmp(name, "renamelimit"))
112 ctx.cfg.renamelimit = atoi(value); 114 ctx.cfg.renamelimit = atoi(value);
113 else if (!strcmp(name, "robots")) 115 else if (!strcmp(name, "robots"))
114 ctx.cfg.robots = xstrdup(value); 116 ctx.cfg.robots = xstrdup(value);
115 else if (!strcmp(name, "clone-prefix")) 117 else if (!strcmp(name, "clone-prefix"))
116 ctx.cfg.clone_prefix = xstrdup(value); 118 ctx.cfg.clone_prefix = xstrdup(value);
117 else if (!strcmp(name, "local-time")) 119 else if (!strcmp(name, "local-time"))
118 ctx.cfg.local_time = atoi(value); 120 ctx.cfg.local_time = atoi(value);
119 else if (!strcmp(name, "repo.group")) 121 else if (!strcmp(name, "repo.group"))
120 ctx.cfg.repo_group = xstrdup(value); 122 ctx.cfg.repo_group = xstrdup(value);
121 else if (!strcmp(name, "repo.url")) 123 else if (!strcmp(name, "repo.url"))
122 ctx.repo = cgit_add_repo(value); 124 ctx.repo = cgit_add_repo(value);
123 else if (!strcmp(name, "repo.name")) 125 else if (!strcmp(name, "repo.name"))
124 ctx.repo->name = xstrdup(value); 126 ctx.repo->name = xstrdup(value);
125 else if (ctx.repo && !strcmp(name, "repo.path")) 127 else if (ctx.repo && !strcmp(name, "repo.path"))
126 ctx.repo->path = trim_end(value, '/'); 128 ctx.repo->path = trim_end(value, '/');
127 else if (ctx.repo && !strcmp(name, "repo.clone-url")) 129 else if (ctx.repo && !strcmp(name, "repo.clone-url"))
128 ctx.repo->clone_url = xstrdup(value); 130 ctx.repo->clone_url = xstrdup(value);
129 else if (ctx.repo && !strcmp(name, "repo.desc")) 131 else if (ctx.repo && !strcmp(name, "repo.desc"))
130 ctx.repo->desc = xstrdup(value); 132 ctx.repo->desc = xstrdup(value);
131 else if (ctx.repo && !strcmp(name, "repo.owner")) 133 else if (ctx.repo && !strcmp(name, "repo.owner"))
132 ctx.repo->owner = xstrdup(value); 134 ctx.repo->owner = xstrdup(value);
133 else if (ctx.repo && !strcmp(name, "repo.defbranch")) 135 else if (ctx.repo && !strcmp(name, "repo.defbranch"))
134 ctx.repo->defbranch = xstrdup(value); 136 ctx.repo->defbranch = xstrdup(value);
135 else if (ctx.repo && !strcmp(name, "repo.snapshots")) 137 else if (ctx.repo && !strcmp(name, "repo.snapshots"))
136 ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */ 138 ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */
137 else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount")) 139 else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount"))
138 ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); 140 ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value);
139 else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount")) 141 else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount"))
140 ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); 142 ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value);
141 else if (ctx.repo && !strcmp(name, "repo.max-stats")) 143 else if (ctx.repo && !strcmp(name, "repo.max-stats"))
142 ctx.repo->max_stats = cgit_find_stats_period(value, NULL); 144 ctx.repo->max_stats = cgit_find_stats_period(value, NULL);
143 else if (ctx.repo && !strcmp(name, "repo.module-link")) 145 else if (ctx.repo && !strcmp(name, "repo.module-link"))
144 ctx.repo->module_link= xstrdup(value); 146 ctx.repo->module_link= xstrdup(value);
145 else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) { 147 else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) {
146 if (*value == '/') 148 if (*value == '/')
147 ctx.repo->readme = xstrdup(value); 149 ctx.repo->readme = xstrdup(value);
148 else 150 else
149 ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, value)); 151 ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, value));
150 } else if (!strcmp(name, "include")) 152 } else if (!strcmp(name, "include"))
151 parse_configfile(value, config_cb); 153 parse_configfile(value, config_cb);
152} 154}
153 155
154static void querystring_cb(const char *name, const char *value) 156static void querystring_cb(const char *name, const char *value)
155{ 157{
156 if (!strcmp(name,"r")) { 158 if (!strcmp(name,"r")) {
157 ctx.qry.repo = xstrdup(value); 159 ctx.qry.repo = xstrdup(value);
158 ctx.repo = cgit_get_repoinfo(value); 160 ctx.repo = cgit_get_repoinfo(value);
159 } else if (!strcmp(name, "p")) { 161 } else if (!strcmp(name, "p")) {
160 ctx.qry.page = xstrdup(value); 162 ctx.qry.page = xstrdup(value);
161 } else if (!strcmp(name, "url")) { 163 } else if (!strcmp(name, "url")) {
162 ctx.qry.url = xstrdup(value); 164 ctx.qry.url = xstrdup(value);
163 cgit_parse_url(value); 165 cgit_parse_url(value);
164 } else if (!strcmp(name, "qt")) { 166 } else if (!strcmp(name, "qt")) {
165 ctx.qry.grep = xstrdup(value); 167 ctx.qry.grep = xstrdup(value);
166 } else if (!strcmp(name, "q")) { 168 } else if (!strcmp(name, "q")) {
167 ctx.qry.search = xstrdup(value); 169 ctx.qry.search = xstrdup(value);
168 } else if (!strcmp(name, "h")) { 170 } else if (!strcmp(name, "h")) {
169 ctx.qry.head = xstrdup(value); 171 ctx.qry.head = xstrdup(value);
170 ctx.qry.has_symref = 1; 172 ctx.qry.has_symref = 1;
171 } else if (!strcmp(name, "id")) { 173 } else if (!strcmp(name, "id")) {
172 ctx.qry.sha1 = xstrdup(value); 174 ctx.qry.sha1 = xstrdup(value);
173 ctx.qry.has_sha1 = 1; 175 ctx.qry.has_sha1 = 1;
174 } else if (!strcmp(name, "id2")) { 176 } else if (!strcmp(name, "id2")) {
175 ctx.qry.sha2 = xstrdup(value); 177 ctx.qry.sha2 = xstrdup(value);
176 ctx.qry.has_sha1 = 1; 178 ctx.qry.has_sha1 = 1;
177 } else if (!strcmp(name, "ofs")) { 179 } else if (!strcmp(name, "ofs")) {
178 ctx.qry.ofs = atoi(value); 180 ctx.qry.ofs = atoi(value);
179 } else if (!strcmp(name, "path")) { 181 } else if (!strcmp(name, "path")) {
180 ctx.qry.path = trim_end(value, '/'); 182 ctx.qry.path = trim_end(value, '/');
181 } else if (!strcmp(name, "name")) { 183 } else if (!strcmp(name, "name")) {
182 ctx.qry.name = xstrdup(value); 184 ctx.qry.name = xstrdup(value);
183 } else if (!strcmp(name, "mimetype")) { 185 } else if (!strcmp(name, "mimetype")) {
184 ctx.qry.mimetype = xstrdup(value); 186 ctx.qry.mimetype = xstrdup(value);
185 } else if (!strcmp(name, "s")){ 187 } else if (!strcmp(name, "s")){
186 ctx.qry.sort = xstrdup(value); 188 ctx.qry.sort = xstrdup(value);
187 } else if (!strcmp(name, "showmsg")) { 189 } else if (!strcmp(name, "showmsg")) {
188 ctx.qry.showmsg = atoi(value); 190 ctx.qry.showmsg = atoi(value);
189 } else if (!strcmp(name, "period")) { 191 } else if (!strcmp(name, "period")) {
190 ctx.qry.period = xstrdup(value); 192 ctx.qry.period = xstrdup(value);
191 } 193 }
192} 194}
193 195
194static void prepare_context(struct cgit_context *ctx) 196static void prepare_context(struct cgit_context *ctx)
195{ 197{
196 memset(ctx, 0, sizeof(ctx)); 198 memset(ctx, 0, sizeof(ctx));
197 ctx->cfg.agefile = "info/web/last-modified"; 199 ctx->cfg.agefile = "info/web/last-modified";
198 ctx->cfg.nocache = 0; 200 ctx->cfg.nocache = 0;
199 ctx->cfg.cache_size = 0; 201 ctx->cfg.cache_size = 0;
200 ctx->cfg.cache_dynamic_ttl = 5; 202 ctx->cfg.cache_dynamic_ttl = 5;
201 ctx->cfg.cache_max_create_time = 5; 203 ctx->cfg.cache_max_create_time = 5;
202 ctx->cfg.cache_repo_ttl = 5; 204 ctx->cfg.cache_repo_ttl = 5;
203 ctx->cfg.cache_root = CGIT_CACHE_ROOT; 205 ctx->cfg.cache_root = CGIT_CACHE_ROOT;
204 ctx->cfg.cache_root_ttl = 5; 206 ctx->cfg.cache_root_ttl = 5;
205 ctx->cfg.cache_static_ttl = -1; 207 ctx->cfg.cache_static_ttl = -1;
206 ctx->cfg.css = "/cgit.css"; 208 ctx->cfg.css = "/cgit.css";
207 ctx->cfg.logo = "/git-logo.png"; 209 ctx->cfg.logo = "/git-logo.png";
208 ctx->cfg.local_time = 0; 210 ctx->cfg.local_time = 0;
209 ctx->cfg.max_repo_count = 50; 211 ctx->cfg.max_repo_count = 50;
210 ctx->cfg.max_commit_count = 50; 212 ctx->cfg.max_commit_count = 50;
211 ctx->cfg.max_lock_attempts = 5; 213 ctx->cfg.max_lock_attempts = 5;
212 ctx->cfg.max_msg_len = 80; 214 ctx->cfg.max_msg_len = 80;
213 ctx->cfg.max_repodesc_len = 80; 215 ctx->cfg.max_repodesc_len = 80;
214 ctx->cfg.max_stats = 0; 216 ctx->cfg.max_stats = 0;
215 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; 217 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";
216 ctx->cfg.renamelimit = -1; 218 ctx->cfg.renamelimit = -1;
217 ctx->cfg.robots = "index, nofollow"; 219 ctx->cfg.robots = "index, nofollow";
218 ctx->cfg.root_title = "Git repository browser"; 220 ctx->cfg.root_title = "Git repository browser";
219 ctx->cfg.root_desc = "a fast webinterface for the git dscm"; 221 ctx->cfg.root_desc = "a fast webinterface for the git dscm";
220 ctx->cfg.script_name = CGIT_SCRIPT_NAME; 222 ctx->cfg.script_name = CGIT_SCRIPT_NAME;
221 ctx->cfg.summary_branches = 10; 223 ctx->cfg.summary_branches = 10;
222 ctx->cfg.summary_log = 10; 224 ctx->cfg.summary_log = 10;
223 ctx->cfg.summary_tags = 10; 225 ctx->cfg.summary_tags = 10;
224 ctx->page.mimetype = "text/html"; 226 ctx->page.mimetype = "text/html";
225 ctx->page.charset = PAGE_ENCODING; 227 ctx->page.charset = PAGE_ENCODING;
226 ctx->page.filename = NULL; 228 ctx->page.filename = NULL;
227 ctx->page.size = 0; 229 ctx->page.size = 0;
228 ctx->page.modified = time(NULL); 230 ctx->page.modified = time(NULL);
229 ctx->page.expires = ctx->page.modified; 231 ctx->page.expires = ctx->page.modified;
230 ctx->page.etag = NULL; 232 ctx->page.etag = NULL;