summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2009-12-08 17:31:07 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2009-12-08 17:31:07 (UTC)
commit57bb4fdb8419d7c250d4c6146910df3263943951 (patch) (unidiff)
tree3597910405ffaebeff892788b1726d707439a8cb
parent5c34d96f7e000eb47418ac9e39dabf92b767c9f2 (diff)
parentef07ccc72da0270e9298c36046a0187dc359b0da (diff)
downloadcgit-57bb4fdb8419d7c250d4c6146910df3263943951.zip
cgit-57bb4fdb8419d7c250d4c6146910df3263943951.tar.gz
cgit-57bb4fdb8419d7c250d4c6146910df3263943951.tar.bz2
Merge branch 'master' of http://op-co.de/cgit
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--cgit.c3
-rw-r--r--cgit.css5
-rw-r--r--cgit.h1
-rw-r--r--cgitrc.5.txt4
-rwxr-xr-xfilters/syntax-highlighting.sh29
-rw-r--r--ui-tree.c6
6 files changed, 31 insertions, 17 deletions
diff --git a/cgit.c b/cgit.c
index bfde9f9..08cb5d2 100644
--- a/cgit.c
+++ b/cgit.c
@@ -120,96 +120,98 @@ void config_cb(const char *name, const char *value)
120 else if (!strcmp(name, "virtual-root")) { 120 else if (!strcmp(name, "virtual-root")) {
121 ctx.cfg.virtual_root = trim_end(value, '/'); 121 ctx.cfg.virtual_root = trim_end(value, '/');
122 if (!ctx.cfg.virtual_root && (!strcmp(value, "/"))) 122 if (!ctx.cfg.virtual_root && (!strcmp(value, "/")))
123 ctx.cfg.virtual_root = ""; 123 ctx.cfg.virtual_root = "";
124 } else if (!strcmp(name, "nocache")) 124 } else if (!strcmp(name, "nocache"))
125 ctx.cfg.nocache = atoi(value); 125 ctx.cfg.nocache = atoi(value);
126 else if (!strcmp(name, "noplainemail")) 126 else if (!strcmp(name, "noplainemail"))
127 ctx.cfg.noplainemail = atoi(value); 127 ctx.cfg.noplainemail = atoi(value);
128 else if (!strcmp(name, "noheader")) 128 else if (!strcmp(name, "noheader"))
129 ctx.cfg.noheader = atoi(value); 129 ctx.cfg.noheader = atoi(value);
130 else if (!strcmp(name, "snapshots")) 130 else if (!strcmp(name, "snapshots"))
131 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")) 132 else if (!strcmp(name, "enable-filter-overrides"))
133 ctx.cfg.enable_filter_overrides = atoi(value); 133 ctx.cfg.enable_filter_overrides = atoi(value);
134 else if (!strcmp(name, "enable-index-links")) 134 else if (!strcmp(name, "enable-index-links"))
135 ctx.cfg.enable_index_links = atoi(value); 135 ctx.cfg.enable_index_links = atoi(value);
136 else if (!strcmp(name, "enable-log-filecount")) 136 else if (!strcmp(name, "enable-log-filecount"))
137 ctx.cfg.enable_log_filecount = atoi(value); 137 ctx.cfg.enable_log_filecount = atoi(value);
138 else if (!strcmp(name, "enable-log-linecount")) 138 else if (!strcmp(name, "enable-log-linecount"))
139 ctx.cfg.enable_log_linecount = atoi(value); 139 ctx.cfg.enable_log_linecount = atoi(value);
140 else if (!strcmp(name, "enable-tree-linenumbers")) 140 else if (!strcmp(name, "enable-tree-linenumbers"))
141 ctx.cfg.enable_tree_linenumbers = atoi(value); 141 ctx.cfg.enable_tree_linenumbers = atoi(value);
142 else if (!strcmp(name, "max-stats")) 142 else if (!strcmp(name, "max-stats"))
143 ctx.cfg.max_stats = cgit_find_stats_period(value, NULL); 143 ctx.cfg.max_stats = cgit_find_stats_period(value, NULL);
144 else if (!strcmp(name, "cache-size")) 144 else if (!strcmp(name, "cache-size"))
145 ctx.cfg.cache_size = atoi(value); 145 ctx.cfg.cache_size = atoi(value);
146 else if (!strcmp(name, "cache-root")) 146 else if (!strcmp(name, "cache-root"))
147 ctx.cfg.cache_root = xstrdup(value); 147 ctx.cfg.cache_root = xstrdup(value);
148 else if (!strcmp(name, "cache-root-ttl")) 148 else if (!strcmp(name, "cache-root-ttl"))
149 ctx.cfg.cache_root_ttl = atoi(value); 149 ctx.cfg.cache_root_ttl = atoi(value);
150 else if (!strcmp(name, "cache-repo-ttl")) 150 else if (!strcmp(name, "cache-repo-ttl"))
151 ctx.cfg.cache_repo_ttl = atoi(value); 151 ctx.cfg.cache_repo_ttl = atoi(value);
152 else if (!strcmp(name, "cache-scanrc-ttl")) 152 else if (!strcmp(name, "cache-scanrc-ttl"))
153 ctx.cfg.cache_scanrc_ttl = atoi(value); 153 ctx.cfg.cache_scanrc_ttl = atoi(value);
154 else if (!strcmp(name, "cache-static-ttl")) 154 else if (!strcmp(name, "cache-static-ttl"))
155 ctx.cfg.cache_static_ttl = atoi(value); 155 ctx.cfg.cache_static_ttl = atoi(value);
156 else if (!strcmp(name, "cache-dynamic-ttl")) 156 else if (!strcmp(name, "cache-dynamic-ttl"))
157 ctx.cfg.cache_dynamic_ttl = atoi(value); 157 ctx.cfg.cache_dynamic_ttl = atoi(value);
158 else if (!strcmp(name, "about-filter")) 158 else if (!strcmp(name, "about-filter"))
159 ctx.cfg.about_filter = new_filter(value, 0); 159 ctx.cfg.about_filter = new_filter(value, 0);
160 else if (!strcmp(name, "commit-filter")) 160 else if (!strcmp(name, "commit-filter"))
161 ctx.cfg.commit_filter = new_filter(value, 0); 161 ctx.cfg.commit_filter = new_filter(value, 0);
162 else if (!strcmp(name, "embedded")) 162 else if (!strcmp(name, "embedded"))
163 ctx.cfg.embedded = atoi(value); 163 ctx.cfg.embedded = atoi(value);
164 else if (!strcmp(name, "max-message-length")) 164 else if (!strcmp(name, "max-message-length"))
165 ctx.cfg.max_msg_len = atoi(value); 165 ctx.cfg.max_msg_len = atoi(value);
166 else if (!strcmp(name, "max-repodesc-length")) 166 else if (!strcmp(name, "max-repodesc-length"))
167 ctx.cfg.max_repodesc_len = atoi(value); 167 ctx.cfg.max_repodesc_len = atoi(value);
168 else if (!strcmp(name, "max-blob-size"))
169 ctx.cfg.max_blob_size = atoi(value);
168 else if (!strcmp(name, "max-repo-count")) 170 else if (!strcmp(name, "max-repo-count"))
169 ctx.cfg.max_repo_count = atoi(value); 171 ctx.cfg.max_repo_count = atoi(value);
170 else if (!strcmp(name, "max-commit-count")) 172 else if (!strcmp(name, "max-commit-count"))
171 ctx.cfg.max_commit_count = atoi(value); 173 ctx.cfg.max_commit_count = atoi(value);
172 else if (!strcmp(name, "scan-path")) 174 else if (!strcmp(name, "scan-path"))
173 if (!ctx.cfg.nocache && ctx.cfg.cache_size) 175 if (!ctx.cfg.nocache && ctx.cfg.cache_size)
174 process_cached_repolist(value); 176 process_cached_repolist(value);
175 else 177 else
176 scan_tree(value, repo_config); 178 scan_tree(value, repo_config);
177 else if (!strcmp(name, "source-filter")) 179 else if (!strcmp(name, "source-filter"))
178 ctx.cfg.source_filter = new_filter(value, 1); 180 ctx.cfg.source_filter = new_filter(value, 1);
179 else if (!strcmp(name, "summary-log")) 181 else if (!strcmp(name, "summary-log"))
180 ctx.cfg.summary_log = atoi(value); 182 ctx.cfg.summary_log = atoi(value);
181 else if (!strcmp(name, "summary-branches")) 183 else if (!strcmp(name, "summary-branches"))
182 ctx.cfg.summary_branches = atoi(value); 184 ctx.cfg.summary_branches = atoi(value);
183 else if (!strcmp(name, "summary-tags")) 185 else if (!strcmp(name, "summary-tags"))
184 ctx.cfg.summary_tags = atoi(value); 186 ctx.cfg.summary_tags = atoi(value);
185 else if (!strcmp(name, "agefile")) 187 else if (!strcmp(name, "agefile"))
186 ctx.cfg.agefile = xstrdup(value); 188 ctx.cfg.agefile = xstrdup(value);
187 else if (!strcmp(name, "renamelimit")) 189 else if (!strcmp(name, "renamelimit"))
188 ctx.cfg.renamelimit = atoi(value); 190 ctx.cfg.renamelimit = atoi(value);
189 else if (!strcmp(name, "robots")) 191 else if (!strcmp(name, "robots"))
190 ctx.cfg.robots = xstrdup(value); 192 ctx.cfg.robots = xstrdup(value);
191 else if (!strcmp(name, "clone-prefix")) 193 else if (!strcmp(name, "clone-prefix"))
192 ctx.cfg.clone_prefix = xstrdup(value); 194 ctx.cfg.clone_prefix = xstrdup(value);
193 else if (!strcmp(name, "local-time")) 195 else if (!strcmp(name, "local-time"))
194 ctx.cfg.local_time = atoi(value); 196 ctx.cfg.local_time = atoi(value);
195 else if (!prefixcmp(name, "mimetype.")) 197 else if (!prefixcmp(name, "mimetype."))
196 add_mimetype(name + 9, value); 198 add_mimetype(name + 9, value);
197 else if (!strcmp(name, "include")) 199 else if (!strcmp(name, "include"))
198 parse_configfile(value, config_cb); 200 parse_configfile(value, config_cb);
199} 201}
200 202
201static void querystring_cb(const char *name, const char *value) 203static void querystring_cb(const char *name, const char *value)
202{ 204{
203 if (!value) 205 if (!value)
204 value = ""; 206 value = "";
205 207
206 if (!strcmp(name,"r")) { 208 if (!strcmp(name,"r")) {
207 ctx.qry.repo = xstrdup(value); 209 ctx.qry.repo = xstrdup(value);
208 ctx.repo = cgit_get_repoinfo(value); 210 ctx.repo = cgit_get_repoinfo(value);
209 } else if (!strcmp(name, "p")) { 211 } else if (!strcmp(name, "p")) {
210 ctx.qry.page = xstrdup(value); 212 ctx.qry.page = xstrdup(value);
211 } else if (!strcmp(name, "url")) { 213 } else if (!strcmp(name, "url")) {
212 if (*value == '/') 214 if (*value == '/')
213 value++; 215 value++;
214 ctx.qry.url = xstrdup(value); 216 ctx.qry.url = xstrdup(value);
215 cgit_parse_url(value); 217 cgit_parse_url(value);
@@ -225,96 +227,97 @@ static void querystring_cb(const char *name, const char *value)
225 ctx.qry.has_sha1 = 1; 227 ctx.qry.has_sha1 = 1;
226 } else if (!strcmp(name, "id2")) { 228 } else if (!strcmp(name, "id2")) {
227 ctx.qry.sha2 = xstrdup(value); 229 ctx.qry.sha2 = xstrdup(value);
228 ctx.qry.has_sha1 = 1; 230 ctx.qry.has_sha1 = 1;
229 } else if (!strcmp(name, "ofs")) { 231 } else if (!strcmp(name, "ofs")) {
230 ctx.qry.ofs = atoi(value); 232 ctx.qry.ofs = atoi(value);
231 } else if (!strcmp(name, "path")) { 233 } else if (!strcmp(name, "path")) {
232 ctx.qry.path = trim_end(value, '/'); 234 ctx.qry.path = trim_end(value, '/');
233 } else if (!strcmp(name, "name")) { 235 } else if (!strcmp(name, "name")) {
234 ctx.qry.name = xstrdup(value); 236 ctx.qry.name = xstrdup(value);
235 } else if (!strcmp(name, "mimetype")) { 237 } else if (!strcmp(name, "mimetype")) {
236 ctx.qry.mimetype = xstrdup(value); 238 ctx.qry.mimetype = xstrdup(value);
237 } else if (!strcmp(name, "s")){ 239 } else if (!strcmp(name, "s")){
238 ctx.qry.sort = xstrdup(value); 240 ctx.qry.sort = xstrdup(value);
239 } else if (!strcmp(name, "showmsg")) { 241 } else if (!strcmp(name, "showmsg")) {
240 ctx.qry.showmsg = atoi(value); 242 ctx.qry.showmsg = atoi(value);
241 } else if (!strcmp(name, "period")) { 243 } else if (!strcmp(name, "period")) {
242 ctx.qry.period = xstrdup(value); 244 ctx.qry.period = xstrdup(value);
243 } 245 }
244} 246}
245 247
246char *xstrdupn(const char *str) 248char *xstrdupn(const char *str)
247{ 249{
248 return (str ? xstrdup(str) : NULL); 250 return (str ? xstrdup(str) : NULL);
249} 251}
250 252
251static void prepare_context(struct cgit_context *ctx) 253static void prepare_context(struct cgit_context *ctx)
252{ 254{
253 memset(ctx, 0, sizeof(ctx)); 255 memset(ctx, 0, sizeof(ctx));
254 ctx->cfg.agefile = "info/web/last-modified"; 256 ctx->cfg.agefile = "info/web/last-modified";
255 ctx->cfg.nocache = 0; 257 ctx->cfg.nocache = 0;
256 ctx->cfg.cache_size = 0; 258 ctx->cfg.cache_size = 0;
257 ctx->cfg.cache_dynamic_ttl = 5; 259 ctx->cfg.cache_dynamic_ttl = 5;
258 ctx->cfg.cache_max_create_time = 5; 260 ctx->cfg.cache_max_create_time = 5;
259 ctx->cfg.cache_repo_ttl = 5; 261 ctx->cfg.cache_repo_ttl = 5;
260 ctx->cfg.cache_root = CGIT_CACHE_ROOT; 262 ctx->cfg.cache_root = CGIT_CACHE_ROOT;
261 ctx->cfg.cache_root_ttl = 5; 263 ctx->cfg.cache_root_ttl = 5;
262 ctx->cfg.cache_scanrc_ttl = 15; 264 ctx->cfg.cache_scanrc_ttl = 15;
263 ctx->cfg.cache_static_ttl = -1; 265 ctx->cfg.cache_static_ttl = -1;
264 ctx->cfg.css = "/cgit.css"; 266 ctx->cfg.css = "/cgit.css";
265 ctx->cfg.logo = "/cgit.png"; 267 ctx->cfg.logo = "/cgit.png";
266 ctx->cfg.local_time = 0; 268 ctx->cfg.local_time = 0;
267 ctx->cfg.enable_tree_linenumbers = 1; 269 ctx->cfg.enable_tree_linenumbers = 1;
268 ctx->cfg.max_repo_count = 50; 270 ctx->cfg.max_repo_count = 50;
269 ctx->cfg.max_commit_count = 50; 271 ctx->cfg.max_commit_count = 50;
270 ctx->cfg.max_lock_attempts = 5; 272 ctx->cfg.max_lock_attempts = 5;
271 ctx->cfg.max_msg_len = 80; 273 ctx->cfg.max_msg_len = 80;
272 ctx->cfg.max_repodesc_len = 80; 274 ctx->cfg.max_repodesc_len = 80;
275 ctx->cfg.max_blob_size = 0;
273 ctx->cfg.max_stats = 0; 276 ctx->cfg.max_stats = 0;
274 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; 277 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";
275 ctx->cfg.renamelimit = -1; 278 ctx->cfg.renamelimit = -1;
276 ctx->cfg.robots = "index, nofollow"; 279 ctx->cfg.robots = "index, nofollow";
277 ctx->cfg.root_title = "Git repository browser"; 280 ctx->cfg.root_title = "Git repository browser";
278 ctx->cfg.root_desc = "a fast webinterface for the git dscm"; 281 ctx->cfg.root_desc = "a fast webinterface for the git dscm";
279 ctx->cfg.script_name = CGIT_SCRIPT_NAME; 282 ctx->cfg.script_name = CGIT_SCRIPT_NAME;
280 ctx->cfg.section = ""; 283 ctx->cfg.section = "";
281 ctx->cfg.summary_branches = 10; 284 ctx->cfg.summary_branches = 10;
282 ctx->cfg.summary_log = 10; 285 ctx->cfg.summary_log = 10;
283 ctx->cfg.summary_tags = 10; 286 ctx->cfg.summary_tags = 10;
284 ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG")); 287 ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG"));
285 ctx->env.http_host = xstrdupn(getenv("HTTP_HOST")); 288 ctx->env.http_host = xstrdupn(getenv("HTTP_HOST"));
286 ctx->env.https = xstrdupn(getenv("HTTPS")); 289 ctx->env.https = xstrdupn(getenv("HTTPS"));
287 ctx->env.no_http = xstrdupn(getenv("NO_HTTP")); 290 ctx->env.no_http = xstrdupn(getenv("NO_HTTP"));
288 ctx->env.path_info = xstrdupn(getenv("PATH_INFO")); 291 ctx->env.path_info = xstrdupn(getenv("PATH_INFO"));
289 ctx->env.query_string = xstrdupn(getenv("QUERY_STRING")); 292 ctx->env.query_string = xstrdupn(getenv("QUERY_STRING"));
290 ctx->env.request_method = xstrdupn(getenv("REQUEST_METHOD")); 293 ctx->env.request_method = xstrdupn(getenv("REQUEST_METHOD"));
291 ctx->env.script_name = xstrdupn(getenv("SCRIPT_NAME")); 294 ctx->env.script_name = xstrdupn(getenv("SCRIPT_NAME"));
292 ctx->env.server_name = xstrdupn(getenv("SERVER_NAME")); 295 ctx->env.server_name = xstrdupn(getenv("SERVER_NAME"));
293 ctx->env.server_port = xstrdupn(getenv("SERVER_PORT")); 296 ctx->env.server_port = xstrdupn(getenv("SERVER_PORT"));
294 ctx->page.mimetype = "text/html"; 297 ctx->page.mimetype = "text/html";
295 ctx->page.charset = PAGE_ENCODING; 298 ctx->page.charset = PAGE_ENCODING;
296 ctx->page.filename = NULL; 299 ctx->page.filename = NULL;
297 ctx->page.size = 0; 300 ctx->page.size = 0;
298 ctx->page.modified = time(NULL); 301 ctx->page.modified = time(NULL);
299 ctx->page.expires = ctx->page.modified; 302 ctx->page.expires = ctx->page.modified;
300 ctx->page.etag = NULL; 303 ctx->page.etag = NULL;
301 memset(&ctx->cfg.mimetypes, 0, sizeof(struct string_list)); 304 memset(&ctx->cfg.mimetypes, 0, sizeof(struct string_list));
302 if (ctx->env.script_name) 305 if (ctx->env.script_name)
303 ctx->cfg.script_name = ctx->env.script_name; 306 ctx->cfg.script_name = ctx->env.script_name;
304 if (ctx->env.query_string) 307 if (ctx->env.query_string)
305 ctx->qry.raw = ctx->env.query_string; 308 ctx->qry.raw = ctx->env.query_string;
306 if (!ctx->env.cgit_config) 309 if (!ctx->env.cgit_config)
307 ctx->env.cgit_config = CGIT_CONFIG; 310 ctx->env.cgit_config = CGIT_CONFIG;
308} 311}
309 312
310struct refmatch { 313struct refmatch {
311 char *req_ref; 314 char *req_ref;
312 char *first_ref; 315 char *first_ref;
313 int match; 316 int match;
314}; 317};
315 318
316int find_current_ref(const char *refname, const unsigned char *sha1, 319int find_current_ref(const char *refname, const unsigned char *sha1,
317 int flags, void *cb_data) 320 int flags, void *cb_data)
318{ 321{
319 struct refmatch *info; 322 struct refmatch *info;
320 323
diff --git a/cgit.css b/cgit.css
index c47ebc9..ef7d3c1 100644
--- a/cgit.css
+++ b/cgit.css
@@ -117,96 +117,101 @@ table.list {
117} 117}
118 118
119table.list tr { 119table.list tr {
120 background: white; 120 background: white;
121} 121}
122 122
123table.list tr.logheader { 123table.list tr.logheader {
124 background: #eee; 124 background: #eee;
125} 125}
126 126
127table.list tr:hover { 127table.list tr:hover {
128 background: #eee; 128 background: #eee;
129} 129}
130 130
131table.list tr.nohover:hover { 131table.list tr.nohover:hover {
132 background: white; 132 background: white;
133} 133}
134 134
135table.list th { 135table.list th {
136 font-weight: bold; 136 font-weight: bold;
137 /* color: #888; 137 /* color: #888;
138 border-top: dashed 1px #888; 138 border-top: dashed 1px #888;
139 border-bottom: dashed 1px #888; 139 border-bottom: dashed 1px #888;
140 */ 140 */
141 padding: 0.1em 0.5em 0.05em 0.5em; 141 padding: 0.1em 0.5em 0.05em 0.5em;
142 vertical-align: baseline; 142 vertical-align: baseline;
143} 143}
144 144
145table.list td { 145table.list td {
146 border: none; 146 border: none;
147 padding: 0.1em 0.5em 0.1em 0.5em; 147 padding: 0.1em 0.5em 0.1em 0.5em;
148} 148}
149 149
150table.list td.logsubject { 150table.list td.logsubject {
151 font-family: monospace; 151 font-family: monospace;
152 font-weight: bold; 152 font-weight: bold;
153} 153}
154 154
155table.list td.logmsg { 155table.list td.logmsg {
156 font-family: monospace; 156 font-family: monospace;
157 white-space: pre; 157 white-space: pre;
158 padding: 1em 0.5em 2em 0.5em; 158 padding: 1em 0.5em 2em 0.5em;
159} 159}
160 160
161table.list td a { 161table.list td a {
162 color: black; 162 color: black;
163} 163}
164 164
165table.list td a.ls-dir {
166 font-weight: bold;
167 color: #00f;
168}
169
165table.list td a:hover { 170table.list td a:hover {
166 color: #00f; 171 color: #00f;
167} 172}
168 173
169img { 174img {
170 border: none; 175 border: none;
171} 176}
172 177
173input#switch-btn { 178input#switch-btn {
174 margin: 2px 0px 0px 0px; 179 margin: 2px 0px 0px 0px;
175} 180}
176 181
177td#sidebar input.txt { 182td#sidebar input.txt {
178 width: 100%; 183 width: 100%;
179 margin: 2px 0px 0px 0px; 184 margin: 2px 0px 0px 0px;
180} 185}
181 186
182table#grid { 187table#grid {
183 margin: 0px; 188 margin: 0px;
184} 189}
185 190
186td#content { 191td#content {
187 vertical-align: top; 192 vertical-align: top;
188 padding: 1em 2em 1em 1em; 193 padding: 1em 2em 1em 1em;
189 border: none; 194 border: none;
190} 195}
191 196
192div#summary { 197div#summary {
193 vertical-align: top; 198 vertical-align: top;
194 margin-bottom: 1em; 199 margin-bottom: 1em;
195} 200}
196 201
197table#downloads { 202table#downloads {
198 float: right; 203 float: right;
199 border-collapse: collapse; 204 border-collapse: collapse;
200 border: solid 1px #777; 205 border: solid 1px #777;
201 margin-left: 0.5em; 206 margin-left: 0.5em;
202 margin-bottom: 0.5em; 207 margin-bottom: 0.5em;
203} 208}
204 209
205table#downloads th { 210table#downloads th {
206 background-color: #ccc; 211 background-color: #ccc;
207} 212}
208 213
209div#blob { 214div#blob {
210 border: solid 1px black; 215 border: solid 1px black;
211} 216}
212 217
diff --git a/cgit.h b/cgit.h
index 6c6c460..39853df 100644
--- a/cgit.h
+++ b/cgit.h
@@ -140,96 +140,97 @@ struct cgit_query {
140 char *url; 140 char *url;
141 char *period; 141 char *period;
142 int ofs; 142 int ofs;
143 int nohead; 143 int nohead;
144 char *sort; 144 char *sort;
145 int showmsg; 145 int showmsg;
146}; 146};
147 147
148struct cgit_config { 148struct cgit_config {
149 char *agefile; 149 char *agefile;
150 char *cache_root; 150 char *cache_root;
151 char *clone_prefix; 151 char *clone_prefix;
152 char *css; 152 char *css;
153 char *favicon; 153 char *favicon;
154 char *footer; 154 char *footer;
155 char *head_include; 155 char *head_include;
156 char *header; 156 char *header;
157 char *index_header; 157 char *index_header;
158 char *index_info; 158 char *index_info;
159 char *logo; 159 char *logo;
160 char *logo_link; 160 char *logo_link;
161 char *module_link; 161 char *module_link;
162 char *robots; 162 char *robots;
163 char *root_title; 163 char *root_title;
164 char *root_desc; 164 char *root_desc;
165 char *root_readme; 165 char *root_readme;
166 char *script_name; 166 char *script_name;
167 char *section; 167 char *section;
168 char *virtual_root; 168 char *virtual_root;
169 int cache_size; 169 int cache_size;
170 int cache_dynamic_ttl; 170 int cache_dynamic_ttl;
171 int cache_max_create_time; 171 int cache_max_create_time;
172 int cache_repo_ttl; 172 int cache_repo_ttl;
173 int cache_root_ttl; 173 int cache_root_ttl;
174 int cache_scanrc_ttl; 174 int cache_scanrc_ttl;
175 int cache_static_ttl; 175 int cache_static_ttl;
176 int embedded; 176 int embedded;
177 int enable_filter_overrides; 177 int enable_filter_overrides;
178 int enable_index_links; 178 int enable_index_links;
179 int enable_log_filecount; 179 int enable_log_filecount;
180 int enable_log_linecount; 180 int enable_log_linecount;
181 int enable_tree_linenumbers; 181 int enable_tree_linenumbers;
182 int local_time; 182 int local_time;
183 int max_repo_count; 183 int max_repo_count;
184 int max_commit_count; 184 int max_commit_count;
185 int max_lock_attempts; 185 int max_lock_attempts;
186 int max_msg_len; 186 int max_msg_len;
187 int max_repodesc_len; 187 int max_repodesc_len;
188 int max_blob_size;
188 int max_stats; 189 int max_stats;
189 int nocache; 190 int nocache;
190 int noplainemail; 191 int noplainemail;
191 int noheader; 192 int noheader;
192 int renamelimit; 193 int renamelimit;
193 int snapshots; 194 int snapshots;
194 int summary_branches; 195 int summary_branches;
195 int summary_log; 196 int summary_log;
196 int summary_tags; 197 int summary_tags;
197 struct string_list mimetypes; 198 struct string_list mimetypes;
198 struct cgit_filter *about_filter; 199 struct cgit_filter *about_filter;
199 struct cgit_filter *commit_filter; 200 struct cgit_filter *commit_filter;
200 struct cgit_filter *source_filter; 201 struct cgit_filter *source_filter;
201}; 202};
202 203
203struct cgit_page { 204struct cgit_page {
204 time_t modified; 205 time_t modified;
205 time_t expires; 206 time_t expires;
206 size_t size; 207 size_t size;
207 char *mimetype; 208 char *mimetype;
208 char *charset; 209 char *charset;
209 char *filename; 210 char *filename;
210 char *etag; 211 char *etag;
211 char *title; 212 char *title;
212 int status; 213 int status;
213 char *statusmsg; 214 char *statusmsg;
214}; 215};
215 216
216struct cgit_environment { 217struct cgit_environment {
217 char *cgit_config; 218 char *cgit_config;
218 char *http_host; 219 char *http_host;
219 char *https; 220 char *https;
220 char *no_http; 221 char *no_http;
221 char *path_info; 222 char *path_info;
222 char *query_string; 223 char *query_string;
223 char *request_method; 224 char *request_method;
224 char *script_name; 225 char *script_name;
225 char *server_name; 226 char *server_name;
226 char *server_port; 227 char *server_port;
227}; 228};
228 229
229struct cgit_context { 230struct cgit_context {
230 struct cgit_environment env; 231 struct cgit_environment env;
231 struct cgit_query qry; 232 struct cgit_query qry;
232 struct cgit_config cfg; 233 struct cgit_config cfg;
233 struct cgit_repo *repo; 234 struct cgit_repo *repo;
234 struct cgit_page page; 235 struct cgit_page page;
235}; 236};
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 0c13485..e69140b 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -132,96 +132,100 @@ header::
132 The content of the file specified with this option will be included 132 The content of the file specified with this option will be included
133 verbatim at the top of all pages. Default value: none. 133 verbatim at the top of all pages. Default value: none.
134 134
135include:: 135include::
136 Name of a configfile to include before the rest of the current config- 136 Name of a configfile to include before the rest of the current config-
137 file is parsed. Default value: none. 137 file is parsed. Default value: none.
138 138
139index-header:: 139index-header::
140 The content of the file specified with this option will be included 140 The content of the file specified with this option will be included
141 verbatim above the repository index. This setting is deprecated, and 141 verbatim above the repository index. This setting is deprecated, and
142 will not be supported by cgit-1.0 (use root-readme instead). Default 142 will not be supported by cgit-1.0 (use root-readme instead). Default
143 value: none. 143 value: none.
144 144
145index-info:: 145index-info::
146 The content of the file specified with this option will be included 146 The content of the file specified with this option will be included
147 verbatim below the heading on the repository index page. This setting 147 verbatim below the heading on the repository index page. This setting
148 is deprecated, and will not be supported by cgit-1.0 (use root-desc 148 is deprecated, and will not be supported by cgit-1.0 (use root-desc
149 instead). Default value: none. 149 instead). Default value: none.
150 150
151local-time:: 151local-time::
152 Flag which, if set to "1", makes cgit print commit and tag times in the 152 Flag which, if set to "1", makes cgit print commit and tag times in the
153 servers timezone. Default value: "0". 153 servers timezone. Default value: "0".
154 154
155logo:: 155logo::
156 Url which specifies the source of an image which will be used as a logo 156 Url which specifies the source of an image which will be used as a logo
157 on all cgit pages. Default value: "/cgit.png". 157 on all cgit pages. Default value: "/cgit.png".
158 158
159logo-link:: 159logo-link::
160 Url loaded when clicking on the cgit logo image. If unspecified the 160 Url loaded when clicking on the cgit logo image. If unspecified the
161 calculated url of the repository index page will be used. Default 161 calculated url of the repository index page will be used. Default
162 value: none. 162 value: none.
163 163
164max-commit-count:: 164max-commit-count::
165 Specifies the number of entries to list per page in "log" view. Default 165 Specifies the number of entries to list per page in "log" view. Default
166 value: "50". 166 value: "50".
167 167
168max-message-length:: 168max-message-length::
169 Specifies the maximum number of commit message characters to display in 169 Specifies the maximum number of commit message characters to display in
170 "log" view. Default value: "80". 170 "log" view. Default value: "80".
171 171
172max-repo-count:: 172max-repo-count::
173 Specifies the number of entries to list per page on therepository 173 Specifies the number of entries to list per page on therepository
174 index page. Default value: "50". 174 index page. Default value: "50".
175 175
176max-repodesc-length:: 176max-repodesc-length::
177 Specifies the maximum number of repo description characters to display 177 Specifies the maximum number of repo description characters to display
178 on the repository index page. Default value: "80". 178 on the repository index page. Default value: "80".
179 179
180max-blob-size::
181 Specifies the maximum size of a blob to display HTML for in KBytes.
182 Default value: "0" (limit disabled).
183
180max-stats:: 184max-stats::
181 Set the default maximum statistics period. Valid values are "week", 185 Set the default maximum statistics period. Valid values are "week",
182 "month", "quarter" and "year". If unspecified, statistics are 186 "month", "quarter" and "year". If unspecified, statistics are
183 disabled. Default value: none. See also: "repo.max-stats". 187 disabled. Default value: none. See also: "repo.max-stats".
184 188
185mimetype.<ext>:: 189mimetype.<ext>::
186 Set the mimetype for the specified filename extension. This is used 190 Set the mimetype for the specified filename extension. This is used
187 by the `plain` command when returning blob content. 191 by the `plain` command when returning blob content.
188 192
189module-link:: 193module-link::
190 Text which will be used as the formatstring for a hyperlink when a 194 Text which will be used as the formatstring for a hyperlink when a
191 submodule is printed in a directory listing. The arguments for the 195 submodule is printed in a directory listing. The arguments for the
192 formatstring are the path and SHA1 of the submodule commit. Default 196 formatstring are the path and SHA1 of the submodule commit. Default
193 value: "./?repo=%s&page=commit&id=%s" 197 value: "./?repo=%s&page=commit&id=%s"
194 198
195nocache:: 199nocache::
196 If set to the value "1" caching will be disabled. This settings is 200 If set to the value "1" caching will be disabled. This settings is
197 deprecated, and will not be honored starting with cgit-1.0. Default 201 deprecated, and will not be honored starting with cgit-1.0. Default
198 value: "0". 202 value: "0".
199 203
200noplainemail:: 204noplainemail::
201 If set to "1" showing full author email adresses will be disabled. 205 If set to "1" showing full author email adresses will be disabled.
202 Default value: "0". 206 Default value: "0".
203 207
204noheader:: 208noheader::
205 Flag which, when set to "1", will make cgit omit the standard header 209 Flag which, when set to "1", will make cgit omit the standard header
206 on all pages. Default value: none. See also: "embedded". 210 on all pages. Default value: none. See also: "embedded".
207 211
208renamelimit:: 212renamelimit::
209 Maximum number of files to consider when detecting renames. The value 213 Maximum number of files to consider when detecting renames. The value
210 "-1" uses the compiletime value in git (for further info, look at 214 "-1" uses the compiletime value in git (for further info, look at
211 `man git-diff`). Default value: "-1". 215 `man git-diff`). Default value: "-1".
212 216
213repo.group:: 217repo.group::
214 Legacy alias for "section". This option is deprecated and will not be 218 Legacy alias for "section". This option is deprecated and will not be
215 supported in cgit-1.0. 219 supported in cgit-1.0.
216 220
217robots:: 221robots::
218 Text used as content for the "robots" meta-tag. Default value: 222 Text used as content for the "robots" meta-tag. Default value:
219 "index, nofollow". 223 "index, nofollow".
220 224
221root-desc:: 225root-desc::
222 Text printed below the heading on the repository index page. Default 226 Text printed below the heading on the repository index page. Default
223 value: "a fast webinterface for the git dscm". 227 value: "a fast webinterface for the git dscm".
224 228
225root-readme:: 229root-readme::
226 The content of the file specified with this option will be included 230 The content of the file specified with this option will be included
227 verbatim below the "about" link on the repository index page. Default 231 verbatim below the "about" link on the repository index page. Default
diff --git a/filters/syntax-highlighting.sh b/filters/syntax-highlighting.sh
index 999ad0c..6b1c576 100755
--- a/filters/syntax-highlighting.sh
+++ b/filters/syntax-highlighting.sh
@@ -1,39 +1,34 @@
1#!/bin/sh 1#!/bin/sh
2# This script can be used to implement syntax highlighting in the cgit 2# This script can be used to implement syntax highlighting in the cgit
3# tree-view by refering to this file with the source-filter or repo.source- 3# tree-view by refering to this file with the source-filter or repo.source-
4# filter options in cgitrc. 4# filter options in cgitrc.
5# 5#
6# This script requires a shell supporting the ${var##pattern} syntax.
7# It is supported by at least dash and bash, however busybox environments
8# might have to use an external call to sed instead.
9#
6# Note: the highlight command (http://www.andre-simon.de/) uses css for syntax 10# Note: the highlight command (http://www.andre-simon.de/) uses css for syntax
7# highlighting, so you'll probably want something like the following included 11# highlighting, so you'll probably want something like the following included
8# in your css file (generated by highlight 2.4.8 and adapted for cgit): 12# in your css file (generated by highlight 2.4.8 and adapted for cgit):
9# 13#
10# table.blob .num { color:#2928ff; } 14# table.blob .num { color:#2928ff; }
11# table.blob .esc { color:#ff00ff; } 15# table.blob .esc { color:#ff00ff; }
12# table.blob .str { color:#ff0000; } 16# table.blob .str { color:#ff0000; }
13# table.blob .dstr { color:#818100; } 17# table.blob .dstr { color:#818100; }
14# table.blob .slc { color:#838183; font-style:italic; } 18# table.blob .slc { color:#838183; font-style:italic; }
15# table.blob .com { color:#838183; font-style:italic; } 19# table.blob .com { color:#838183; font-style:italic; }
16# table.blob .dir { color:#008200; } 20# table.blob .dir { color:#008200; }
17# table.blob .sym { color:#000000; } 21# table.blob .sym { color:#000000; }
18# table.blob .kwa { color:#000000; font-weight:bold; } 22# table.blob .kwa { color:#000000; font-weight:bold; }
19# table.blob .kwb { color:#830000; } 23# table.blob .kwb { color:#830000; }
20# table.blob .kwc { color:#000000; font-weight:bold; } 24# table.blob .kwc { color:#000000; font-weight:bold; }
21# table.blob .kwd { color:#010181; } 25# table.blob .kwd { color:#010181; }
22 26
23case "$1" in 27# store filename and extension in local vars
24 *.c) 28BASENAME="$1"
25 highlight -f -I -X -S c 29EXTENSION="${BASENAME##*.}"
26 ;; 30
27 *.h) 31# map Makefile and Makefile.* to .mk
28 highlight -f -I -X -S c 32[ "${BASENAME%%.*}" == "Makefile" ] && EXTENSION=mk
29 ;; 33
30 *.sh) 34exec highlight --force -f -I -X -S $EXTENSION 2>/dev/null
31 highlight -f -I -X -S sh
32 ;;
33 *.css)
34 highlight -f -I -X -S css
35 ;;
36 *)
37 highlight -f -I -X -S txt
38 ;;
39esac
diff --git a/ui-tree.c b/ui-tree.c
index f53ab64..f281937 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -62,96 +62,102 @@ static void print_text_buffer(const char *name, char *buf, unsigned long size)
62static void print_binary_buffer(char *buf, unsigned long size) 62static void print_binary_buffer(char *buf, unsigned long size)
63{ 63{
64 unsigned long ofs, idx; 64 unsigned long ofs, idx;
65 static char ascii[ROWLEN + 1]; 65 static char ascii[ROWLEN + 1];
66 66
67 html("<table summary='blob content' class='bin-blob'>\n"); 67 html("<table summary='blob content' class='bin-blob'>\n");
68 html("<tr><th>ofs</th><th>hex dump</th><th>ascii</th></tr>"); 68 html("<tr><th>ofs</th><th>hex dump</th><th>ascii</th></tr>");
69 for (ofs = 0; ofs < size; ofs += ROWLEN, buf += ROWLEN) { 69 for (ofs = 0; ofs < size; ofs += ROWLEN, buf += ROWLEN) {
70 htmlf("<tr><td class='right'>%04x</td><td class='hex'>", ofs); 70 htmlf("<tr><td class='right'>%04x</td><td class='hex'>", ofs);
71 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++) 71 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++)
72 htmlf("%*s%02x", 72 htmlf("%*s%02x",
73 idx == 16 ? 4 : 1, "", 73 idx == 16 ? 4 : 1, "",
74 buf[idx] & 0xff); 74 buf[idx] & 0xff);
75 html(" </td><td class='hex'>"); 75 html(" </td><td class='hex'>");
76 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++) 76 for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++)
77 ascii[idx] = isgraph(buf[idx]) ? buf[idx] : '.'; 77 ascii[idx] = isgraph(buf[idx]) ? buf[idx] : '.';
78 ascii[idx] = '\0'; 78 ascii[idx] = '\0';
79 html_txt(ascii); 79 html_txt(ascii);
80 html("</td></tr>\n"); 80 html("</td></tr>\n");
81 } 81 }
82 html("</table>\n"); 82 html("</table>\n");
83} 83}
84 84
85static void print_object(const unsigned char *sha1, char *path, const char *basename) 85static void print_object(const unsigned char *sha1, char *path, const char *basename)
86{ 86{
87 enum object_type type; 87 enum object_type type;
88 char *buf; 88 char *buf;
89 unsigned long size; 89 unsigned long size;
90 90
91 type = sha1_object_info(sha1, &size); 91 type = sha1_object_info(sha1, &size);
92 if (type == OBJ_BAD) { 92 if (type == OBJ_BAD) {
93 cgit_print_error(fmt("Bad object name: %s", 93 cgit_print_error(fmt("Bad object name: %s",
94 sha1_to_hex(sha1))); 94 sha1_to_hex(sha1)));
95 return; 95 return;
96 } 96 }
97 97
98 buf = read_sha1_file(sha1, &type, &size); 98 buf = read_sha1_file(sha1, &type, &size);
99 if (!buf) { 99 if (!buf) {
100 cgit_print_error(fmt("Error reading object %s", 100 cgit_print_error(fmt("Error reading object %s",
101 sha1_to_hex(sha1))); 101 sha1_to_hex(sha1)));
102 return; 102 return;
103 } 103 }
104 104
105 html(" ("); 105 html(" (");
106 cgit_plain_link("plain", NULL, NULL, ctx.qry.head, 106 cgit_plain_link("plain", NULL, NULL, ctx.qry.head,
107 curr_rev, path); 107 curr_rev, path);
108 htmlf(")<br/>blob: %s\n", sha1_to_hex(sha1)); 108 htmlf(")<br/>blob: %s\n", sha1_to_hex(sha1));
109 109
110 if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
111 htmlf("<div class='error'>blob size (%dKB) exceeds display size limit (%dKB).</div>",
112 size / 1024, ctx.cfg.max_blob_size);
113 return;
114 }
115
110 if (buffer_is_binary(buf, size)) 116 if (buffer_is_binary(buf, size))
111 print_binary_buffer(buf, size); 117 print_binary_buffer(buf, size);
112 else 118 else
113 print_text_buffer(basename, buf, size); 119 print_text_buffer(basename, buf, size);
114} 120}
115 121
116 122
117static int ls_item(const unsigned char *sha1, const char *base, int baselen, 123static int ls_item(const unsigned char *sha1, const char *base, int baselen,
118 const char *pathname, unsigned int mode, int stage, 124 const char *pathname, unsigned int mode, int stage,
119 void *cbdata) 125 void *cbdata)
120{ 126{
121 char *name; 127 char *name;
122 char *fullpath; 128 char *fullpath;
123 char *class; 129 char *class;
124 enum object_type type; 130 enum object_type type;
125 unsigned long size = 0; 131 unsigned long size = 0;
126 132
127 name = xstrdup(pathname); 133 name = xstrdup(pathname);
128 fullpath = fmt("%s%s%s", ctx.qry.path ? ctx.qry.path : "", 134 fullpath = fmt("%s%s%s", ctx.qry.path ? ctx.qry.path : "",
129 ctx.qry.path ? "/" : "", name); 135 ctx.qry.path ? "/" : "", name);
130 136
131 if (!S_ISGITLINK(mode)) { 137 if (!S_ISGITLINK(mode)) {
132 type = sha1_object_info(sha1, &size); 138 type = sha1_object_info(sha1, &size);
133 if (type == OBJ_BAD) { 139 if (type == OBJ_BAD) {
134 htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>", 140 htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>",
135 name, 141 name,
136 sha1_to_hex(sha1)); 142 sha1_to_hex(sha1));
137 return 0; 143 return 0;
138 } 144 }
139 } 145 }
140 146
141 html("<tr><td class='ls-mode'>"); 147 html("<tr><td class='ls-mode'>");
142 cgit_print_filemode(mode); 148 cgit_print_filemode(mode);
143 html("</td><td>"); 149 html("</td><td>");
144 if (S_ISGITLINK(mode)) { 150 if (S_ISGITLINK(mode)) {
145 htmlf("<a class='ls-mod' href='"); 151 htmlf("<a class='ls-mod' href='");
146 html_attr(fmt(ctx.repo->module_link, 152 html_attr(fmt(ctx.repo->module_link,
147 name, 153 name,
148 sha1_to_hex(sha1))); 154 sha1_to_hex(sha1)));
149 html("'>"); 155 html("'>");
150 html_txt(name); 156 html_txt(name);
151 html("</a>"); 157 html("</a>");
152 } else if (S_ISDIR(mode)) { 158 } else if (S_ISDIR(mode)) {
153 cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, 159 cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head,
154 curr_rev, fullpath); 160 curr_rev, fullpath);
155 } else { 161 } else {
156 class = strrchr(name, '.'); 162 class = strrchr(name, '.');
157 if (class != NULL) { 163 if (class != NULL) {