summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2010-06-19 09:42:12 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2010-06-19 09:42:12 (UTC)
commitc2766deb67acb1eae2b36dc0f5811a9cabb6db20 (patch) (unidiff)
tree463ea4a4388f2c449dec9eb49b33f9c0942030d1
parentcaf0825d97582d137387b8879867247e92cca022 (diff)
parent80476b0d2873eb212fad38487fd6189bd6629cbe (diff)
downloadcgit-c2766deb67acb1eae2b36dc0f5811a9cabb6db20.zip
cgit-c2766deb67acb1eae2b36dc0f5811a9cabb6db20.tar.gz
cgit-c2766deb67acb1eae2b36dc0f5811a9cabb6db20.tar.bz2
Merge branch 'ag/atom-fixes'
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c5
-rw-r--r--cgit.h2
-rw-r--r--cgitrc.5.txt4
-rw-r--r--cmd.c2
-rw-r--r--ui-atom.c4
5 files changed, 15 insertions, 2 deletions
diff --git a/cgit.c b/cgit.c
index 6ccf4aa..38bc136 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,490 +1,495 @@
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
20void add_mimetype(const char *name, const char *value) 20void add_mimetype(const char *name, const char *value)
21{ 21{
22 struct string_list_item *item; 22 struct string_list_item *item;
23 23
24 item = string_list_insert(xstrdup(name), &ctx.cfg.mimetypes); 24 item = string_list_insert(xstrdup(name), &ctx.cfg.mimetypes);
25 item->util = xstrdup(value); 25 item->util = xstrdup(value);
26} 26}
27 27
28struct cgit_filter *new_filter(const char *cmd, int extra_args) 28struct cgit_filter *new_filter(const char *cmd, int extra_args)
29{ 29{
30 struct cgit_filter *f; 30 struct cgit_filter *f;
31 31
32 if (!cmd || !cmd[0]) 32 if (!cmd || !cmd[0])
33 return NULL; 33 return NULL;
34 34
35 f = xmalloc(sizeof(struct cgit_filter)); 35 f = xmalloc(sizeof(struct cgit_filter));
36 f->cmd = xstrdup(cmd); 36 f->cmd = xstrdup(cmd);
37 f->argv = xmalloc((2 + extra_args) * sizeof(char *)); 37 f->argv = xmalloc((2 + extra_args) * sizeof(char *));
38 f->argv[0] = f->cmd; 38 f->argv[0] = f->cmd;
39 f->argv[1] = NULL; 39 f->argv[1] = NULL;
40 return f; 40 return f;
41} 41}
42 42
43static void process_cached_repolist(const char *path); 43static void process_cached_repolist(const char *path);
44 44
45void repo_config(struct cgit_repo *repo, const char *name, const char *value) 45void repo_config(struct cgit_repo *repo, const char *name, const char *value)
46{ 46{
47 if (!strcmp(name, "name")) 47 if (!strcmp(name, "name"))
48 repo->name = xstrdup(value); 48 repo->name = xstrdup(value);
49 else if (!strcmp(name, "clone-url")) 49 else if (!strcmp(name, "clone-url"))
50 repo->clone_url = xstrdup(value); 50 repo->clone_url = xstrdup(value);
51 else if (!strcmp(name, "desc")) 51 else if (!strcmp(name, "desc"))
52 repo->desc = xstrdup(value); 52 repo->desc = xstrdup(value);
53 else if (!strcmp(name, "owner")) 53 else if (!strcmp(name, "owner"))
54 repo->owner = xstrdup(value); 54 repo->owner = xstrdup(value);
55 else if (!strcmp(name, "defbranch")) 55 else if (!strcmp(name, "defbranch"))
56 repo->defbranch = xstrdup(value); 56 repo->defbranch = xstrdup(value);
57 else if (!strcmp(name, "snapshots")) 57 else if (!strcmp(name, "snapshots"))
58 repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); 58 repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value);
59 else if (!strcmp(name, "enable-log-filecount")) 59 else if (!strcmp(name, "enable-log-filecount"))
60 repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); 60 repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value);
61 else if (!strcmp(name, "enable-log-linecount")) 61 else if (!strcmp(name, "enable-log-linecount"))
62 repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); 62 repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value);
63 else if (!strcmp(name, "enable-remote-branches")) 63 else if (!strcmp(name, "enable-remote-branches"))
64 repo->enable_remote_branches = atoi(value); 64 repo->enable_remote_branches = atoi(value);
65 else if (!strcmp(name, "enable-subject-links")) 65 else if (!strcmp(name, "enable-subject-links"))
66 repo->enable_subject_links = atoi(value); 66 repo->enable_subject_links = atoi(value);
67 else if (!strcmp(name, "max-stats")) 67 else if (!strcmp(name, "max-stats"))
68 repo->max_stats = cgit_find_stats_period(value, NULL); 68 repo->max_stats = cgit_find_stats_period(value, NULL);
69 else if (!strcmp(name, "module-link")) 69 else if (!strcmp(name, "module-link"))
70 repo->module_link= xstrdup(value); 70 repo->module_link= xstrdup(value);
71 else if (!strcmp(name, "section")) 71 else if (!strcmp(name, "section"))
72 repo->section = xstrdup(value); 72 repo->section = xstrdup(value);
73 else if (!strcmp(name, "readme") && value != NULL) { 73 else if (!strcmp(name, "readme") && value != NULL) {
74 if (*value == '/') 74 if (*value == '/')
75 repo->readme = xstrdup(value); 75 repo->readme = xstrdup(value);
76 else 76 else
77 repo->readme = xstrdup(fmt("%s/%s", repo->path, value)); 77 repo->readme = xstrdup(fmt("%s/%s", repo->path, value));
78 } else if (ctx.cfg.enable_filter_overrides) { 78 } else if (ctx.cfg.enable_filter_overrides) {
79 if (!strcmp(name, "about-filter")) 79 if (!strcmp(name, "about-filter"))
80 repo->about_filter = new_filter(value, 0); 80 repo->about_filter = new_filter(value, 0);
81 else if (!strcmp(name, "commit-filter")) 81 else if (!strcmp(name, "commit-filter"))
82 repo->commit_filter = new_filter(value, 0); 82 repo->commit_filter = new_filter(value, 0);
83 else if (!strcmp(name, "source-filter")) 83 else if (!strcmp(name, "source-filter"))
84 repo->source_filter = new_filter(value, 1); 84 repo->source_filter = new_filter(value, 1);
85 } 85 }
86} 86}
87 87
88void config_cb(const char *name, const char *value) 88void config_cb(const char *name, const char *value)
89{ 89{
90 if (!strcmp(name, "section") || !strcmp(name, "repo.group")) 90 if (!strcmp(name, "section") || !strcmp(name, "repo.group"))
91 ctx.cfg.section = xstrdup(value); 91 ctx.cfg.section = xstrdup(value);
92 else if (!strcmp(name, "repo.url")) 92 else if (!strcmp(name, "repo.url"))
93 ctx.repo = cgit_add_repo(value); 93 ctx.repo = cgit_add_repo(value);
94 else if (ctx.repo && !strcmp(name, "repo.path")) 94 else if (ctx.repo && !strcmp(name, "repo.path"))
95 ctx.repo->path = trim_end(value, '/'); 95 ctx.repo->path = trim_end(value, '/');
96 else if (ctx.repo && !prefixcmp(name, "repo.")) 96 else if (ctx.repo && !prefixcmp(name, "repo."))
97 repo_config(ctx.repo, name + 5, value); 97 repo_config(ctx.repo, name + 5, value);
98 else if (!strcmp(name, "root-title")) 98 else if (!strcmp(name, "root-title"))
99 ctx.cfg.root_title = xstrdup(value); 99 ctx.cfg.root_title = xstrdup(value);
100 else if (!strcmp(name, "root-desc")) 100 else if (!strcmp(name, "root-desc"))
101 ctx.cfg.root_desc = xstrdup(value); 101 ctx.cfg.root_desc = xstrdup(value);
102 else if (!strcmp(name, "root-readme")) 102 else if (!strcmp(name, "root-readme"))
103 ctx.cfg.root_readme = xstrdup(value); 103 ctx.cfg.root_readme = xstrdup(value);
104 else if (!strcmp(name, "css")) 104 else if (!strcmp(name, "css"))
105 ctx.cfg.css = xstrdup(value); 105 ctx.cfg.css = xstrdup(value);
106 else if (!strcmp(name, "favicon")) 106 else if (!strcmp(name, "favicon"))
107 ctx.cfg.favicon = xstrdup(value); 107 ctx.cfg.favicon = xstrdup(value);
108 else if (!strcmp(name, "footer")) 108 else if (!strcmp(name, "footer"))
109 ctx.cfg.footer = xstrdup(value); 109 ctx.cfg.footer = xstrdup(value);
110 else if (!strcmp(name, "head-include")) 110 else if (!strcmp(name, "head-include"))
111 ctx.cfg.head_include = xstrdup(value); 111 ctx.cfg.head_include = xstrdup(value);
112 else if (!strcmp(name, "header")) 112 else if (!strcmp(name, "header"))
113 ctx.cfg.header = xstrdup(value); 113 ctx.cfg.header = xstrdup(value);
114 else if (!strcmp(name, "logo")) 114 else if (!strcmp(name, "logo"))
115 ctx.cfg.logo = xstrdup(value); 115 ctx.cfg.logo = xstrdup(value);
116 else if (!strcmp(name, "index-header")) 116 else if (!strcmp(name, "index-header"))
117 ctx.cfg.index_header = xstrdup(value); 117 ctx.cfg.index_header = xstrdup(value);
118 else if (!strcmp(name, "index-info")) 118 else if (!strcmp(name, "index-info"))
119 ctx.cfg.index_info = xstrdup(value); 119 ctx.cfg.index_info = xstrdup(value);
120 else if (!strcmp(name, "logo-link")) 120 else if (!strcmp(name, "logo-link"))
121 ctx.cfg.logo_link = xstrdup(value); 121 ctx.cfg.logo_link = xstrdup(value);
122 else if (!strcmp(name, "module-link")) 122 else if (!strcmp(name, "module-link"))
123 ctx.cfg.module_link = xstrdup(value); 123 ctx.cfg.module_link = xstrdup(value);
124 else if (!strcmp(name, "virtual-root")) { 124 else if (!strcmp(name, "virtual-root")) {
125 ctx.cfg.virtual_root = trim_end(value, '/'); 125 ctx.cfg.virtual_root = trim_end(value, '/');
126 if (!ctx.cfg.virtual_root && (!strcmp(value, "/"))) 126 if (!ctx.cfg.virtual_root && (!strcmp(value, "/")))
127 ctx.cfg.virtual_root = ""; 127 ctx.cfg.virtual_root = "";
128 } else if (!strcmp(name, "nocache")) 128 } else if (!strcmp(name, "nocache"))
129 ctx.cfg.nocache = atoi(value); 129 ctx.cfg.nocache = atoi(value);
130 else if (!strcmp(name, "noplainemail")) 130 else if (!strcmp(name, "noplainemail"))
131 ctx.cfg.noplainemail = atoi(value); 131 ctx.cfg.noplainemail = atoi(value);
132 else if (!strcmp(name, "noheader")) 132 else if (!strcmp(name, "noheader"))
133 ctx.cfg.noheader = atoi(value); 133 ctx.cfg.noheader = atoi(value);
134 else if (!strcmp(name, "snapshots")) 134 else if (!strcmp(name, "snapshots"))
135 ctx.cfg.snapshots = cgit_parse_snapshots_mask(value); 135 ctx.cfg.snapshots = cgit_parse_snapshots_mask(value);
136 else if (!strcmp(name, "enable-filter-overrides")) 136 else if (!strcmp(name, "enable-filter-overrides"))
137 ctx.cfg.enable_filter_overrides = atoi(value); 137 ctx.cfg.enable_filter_overrides = atoi(value);
138 else if (!strcmp(name, "enable-index-links")) 138 else if (!strcmp(name, "enable-index-links"))
139 ctx.cfg.enable_index_links = atoi(value); 139 ctx.cfg.enable_index_links = atoi(value);
140 else if (!strcmp(name, "enable-log-filecount")) 140 else if (!strcmp(name, "enable-log-filecount"))
141 ctx.cfg.enable_log_filecount = atoi(value); 141 ctx.cfg.enable_log_filecount = atoi(value);
142 else if (!strcmp(name, "enable-log-linecount")) 142 else if (!strcmp(name, "enable-log-linecount"))
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(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);
168 else if (!strcmp(name, "commit-filter")) 168 else if (!strcmp(name, "commit-filter"))
169 ctx.cfg.commit_filter = new_filter(value, 0); 169 ctx.cfg.commit_filter = new_filter(value, 0);
170 else if (!strcmp(name, "embedded")) 170 else if (!strcmp(name, "embedded"))
171 ctx.cfg.embedded = atoi(value); 171 ctx.cfg.embedded = atoi(value);
172 else if (!strcmp(name, "max-atom-items"))
173 ctx.cfg.max_atom_items = atoi(value);
172 else if (!strcmp(name, "max-message-length")) 174 else if (!strcmp(name, "max-message-length"))
173 ctx.cfg.max_msg_len = atoi(value); 175 ctx.cfg.max_msg_len = atoi(value);
174 else if (!strcmp(name, "max-repodesc-length")) 176 else if (!strcmp(name, "max-repodesc-length"))
175 ctx.cfg.max_repodesc_len = atoi(value); 177 ctx.cfg.max_repodesc_len = atoi(value);
176 else if (!strcmp(name, "max-blob-size")) 178 else if (!strcmp(name, "max-blob-size"))
177 ctx.cfg.max_blob_size = atoi(value); 179 ctx.cfg.max_blob_size = atoi(value);
178 else if (!strcmp(name, "max-repo-count")) 180 else if (!strcmp(name, "max-repo-count"))
179 ctx.cfg.max_repo_count = atoi(value); 181 ctx.cfg.max_repo_count = atoi(value);
180 else if (!strcmp(name, "max-commit-count")) 182 else if (!strcmp(name, "max-commit-count"))
181 ctx.cfg.max_commit_count = atoi(value); 183 ctx.cfg.max_commit_count = atoi(value);
182 else if (!strcmp(name, "scan-path")) 184 else if (!strcmp(name, "scan-path"))
183 if (!ctx.cfg.nocache && ctx.cfg.cache_size) 185 if (!ctx.cfg.nocache && ctx.cfg.cache_size)
184 process_cached_repolist(value); 186 process_cached_repolist(value);
185 else 187 else
186 scan_tree(value, repo_config); 188 scan_tree(value, repo_config);
187 else if (!strcmp(name, "source-filter")) 189 else if (!strcmp(name, "source-filter"))
188 ctx.cfg.source_filter = new_filter(value, 1); 190 ctx.cfg.source_filter = new_filter(value, 1);
189 else if (!strcmp(name, "summary-log")) 191 else if (!strcmp(name, "summary-log"))
190 ctx.cfg.summary_log = atoi(value); 192 ctx.cfg.summary_log = atoi(value);
191 else if (!strcmp(name, "summary-branches")) 193 else if (!strcmp(name, "summary-branches"))
192 ctx.cfg.summary_branches = atoi(value); 194 ctx.cfg.summary_branches = atoi(value);
193 else if (!strcmp(name, "summary-tags")) 195 else if (!strcmp(name, "summary-tags"))
194 ctx.cfg.summary_tags = atoi(value); 196 ctx.cfg.summary_tags = atoi(value);
195 else if (!strcmp(name, "side-by-side-diffs")) 197 else if (!strcmp(name, "side-by-side-diffs"))
196 ctx.cfg.ssdiff = atoi(value); 198 ctx.cfg.ssdiff = atoi(value);
197 else if (!strcmp(name, "agefile")) 199 else if (!strcmp(name, "agefile"))
198 ctx.cfg.agefile = xstrdup(value); 200 ctx.cfg.agefile = xstrdup(value);
199 else if (!strcmp(name, "renamelimit")) 201 else if (!strcmp(name, "renamelimit"))
200 ctx.cfg.renamelimit = atoi(value); 202 ctx.cfg.renamelimit = atoi(value);
201 else if (!strcmp(name, "robots")) 203 else if (!strcmp(name, "robots"))
202 ctx.cfg.robots = xstrdup(value); 204 ctx.cfg.robots = xstrdup(value);
203 else if (!strcmp(name, "clone-prefix")) 205 else if (!strcmp(name, "clone-prefix"))
204 ctx.cfg.clone_prefix = xstrdup(value); 206 ctx.cfg.clone_prefix = xstrdup(value);
205 else if (!strcmp(name, "local-time")) 207 else if (!strcmp(name, "local-time"))
206 ctx.cfg.local_time = atoi(value); 208 ctx.cfg.local_time = atoi(value);
207 else if (!prefixcmp(name, "mimetype.")) 209 else if (!prefixcmp(name, "mimetype."))
208 add_mimetype(name + 9, value); 210 add_mimetype(name + 9, value);
209 else if (!strcmp(name, "include")) 211 else if (!strcmp(name, "include"))
210 parse_configfile(value, config_cb); 212 parse_configfile(value, config_cb);
211} 213}
212 214
213static void querystring_cb(const char *name, const char *value) 215static void querystring_cb(const char *name, const char *value)
214{ 216{
215 if (!value) 217 if (!value)
216 value = ""; 218 value = "";
217 219
218 if (!strcmp(name,"r")) { 220 if (!strcmp(name,"r")) {
219 ctx.qry.repo = xstrdup(value); 221 ctx.qry.repo = xstrdup(value);
220 ctx.repo = cgit_get_repoinfo(value); 222 ctx.repo = cgit_get_repoinfo(value);
221 } else if (!strcmp(name, "p")) { 223 } else if (!strcmp(name, "p")) {
222 ctx.qry.page = xstrdup(value); 224 ctx.qry.page = xstrdup(value);
223 } else if (!strcmp(name, "url")) { 225 } else if (!strcmp(name, "url")) {
224 if (*value == '/') 226 if (*value == '/')
225 value++; 227 value++;
226 ctx.qry.url = xstrdup(value); 228 ctx.qry.url = xstrdup(value);
227 cgit_parse_url(value); 229 cgit_parse_url(value);
228 } else if (!strcmp(name, "qt")) { 230 } else if (!strcmp(name, "qt")) {
229 ctx.qry.grep = xstrdup(value); 231 ctx.qry.grep = xstrdup(value);
230 } else if (!strcmp(name, "q")) { 232 } else if (!strcmp(name, "q")) {
231 ctx.qry.search = xstrdup(value); 233 ctx.qry.search = xstrdup(value);
232 } else if (!strcmp(name, "h")) { 234 } else if (!strcmp(name, "h")) {
233 ctx.qry.head = xstrdup(value); 235 ctx.qry.head = xstrdup(value);
234 ctx.qry.has_symref = 1; 236 ctx.qry.has_symref = 1;
235 } else if (!strcmp(name, "id")) { 237 } else if (!strcmp(name, "id")) {
236 ctx.qry.sha1 = xstrdup(value); 238 ctx.qry.sha1 = xstrdup(value);
237 ctx.qry.has_sha1 = 1; 239 ctx.qry.has_sha1 = 1;
238 } else if (!strcmp(name, "id2")) { 240 } else if (!strcmp(name, "id2")) {
239 ctx.qry.sha2 = xstrdup(value); 241 ctx.qry.sha2 = xstrdup(value);
240 ctx.qry.has_sha1 = 1; 242 ctx.qry.has_sha1 = 1;
241 } else if (!strcmp(name, "ofs")) { 243 } else if (!strcmp(name, "ofs")) {
242 ctx.qry.ofs = atoi(value); 244 ctx.qry.ofs = atoi(value);
243 } else if (!strcmp(name, "path")) { 245 } else if (!strcmp(name, "path")) {
244 ctx.qry.path = trim_end(value, '/'); 246 ctx.qry.path = trim_end(value, '/');
245 } else if (!strcmp(name, "name")) { 247 } else if (!strcmp(name, "name")) {
246 ctx.qry.name = xstrdup(value); 248 ctx.qry.name = xstrdup(value);
247 } else if (!strcmp(name, "mimetype")) { 249 } else if (!strcmp(name, "mimetype")) {
248 ctx.qry.mimetype = xstrdup(value); 250 ctx.qry.mimetype = xstrdup(value);
249 } else if (!strcmp(name, "s")){ 251 } else if (!strcmp(name, "s")){
250 ctx.qry.sort = xstrdup(value); 252 ctx.qry.sort = xstrdup(value);
251 } else if (!strcmp(name, "showmsg")) { 253 } else if (!strcmp(name, "showmsg")) {
252 ctx.qry.showmsg = atoi(value); 254 ctx.qry.showmsg = atoi(value);
253 } else if (!strcmp(name, "period")) { 255 } else if (!strcmp(name, "period")) {
254 ctx.qry.period = xstrdup(value); 256 ctx.qry.period = xstrdup(value);
255 } else if (!strcmp(name, "ss")) { 257 } else if (!strcmp(name, "ss")) {
256 ctx.qry.ssdiff = atoi(value); 258 ctx.qry.ssdiff = atoi(value);
259 } else if (!strcmp(name, "all")) {
260 ctx.qry.show_all = atoi(value);
257 } 261 }
258} 262}
259 263
260char *xstrdupn(const char *str) 264char *xstrdupn(const char *str)
261{ 265{
262 return (str ? xstrdup(str) : NULL); 266 return (str ? xstrdup(str) : NULL);
263} 267}
264 268
265static void prepare_context(struct cgit_context *ctx) 269static void prepare_context(struct cgit_context *ctx)
266{ 270{
267 memset(ctx, 0, sizeof(*ctx)); 271 memset(ctx, 0, sizeof(*ctx));
268 ctx->cfg.agefile = "info/web/last-modified"; 272 ctx->cfg.agefile = "info/web/last-modified";
269 ctx->cfg.nocache = 0; 273 ctx->cfg.nocache = 0;
270 ctx->cfg.cache_size = 0; 274 ctx->cfg.cache_size = 0;
271 ctx->cfg.cache_dynamic_ttl = 5; 275 ctx->cfg.cache_dynamic_ttl = 5;
272 ctx->cfg.cache_max_create_time = 5; 276 ctx->cfg.cache_max_create_time = 5;
273 ctx->cfg.cache_repo_ttl = 5; 277 ctx->cfg.cache_repo_ttl = 5;
274 ctx->cfg.cache_root = CGIT_CACHE_ROOT; 278 ctx->cfg.cache_root = CGIT_CACHE_ROOT;
275 ctx->cfg.cache_root_ttl = 5; 279 ctx->cfg.cache_root_ttl = 5;
276 ctx->cfg.cache_scanrc_ttl = 15; 280 ctx->cfg.cache_scanrc_ttl = 15;
277 ctx->cfg.cache_static_ttl = -1; 281 ctx->cfg.cache_static_ttl = -1;
278 ctx->cfg.css = "/cgit.css"; 282 ctx->cfg.css = "/cgit.css";
279 ctx->cfg.logo = "/cgit.png"; 283 ctx->cfg.logo = "/cgit.png";
280 ctx->cfg.local_time = 0; 284 ctx->cfg.local_time = 0;
281 ctx->cfg.enable_tree_linenumbers = 1; 285 ctx->cfg.enable_tree_linenumbers = 1;
282 ctx->cfg.max_repo_count = 50; 286 ctx->cfg.max_repo_count = 50;
283 ctx->cfg.max_commit_count = 50; 287 ctx->cfg.max_commit_count = 50;
284 ctx->cfg.max_lock_attempts = 5; 288 ctx->cfg.max_lock_attempts = 5;
285 ctx->cfg.max_msg_len = 80; 289 ctx->cfg.max_msg_len = 80;
286 ctx->cfg.max_repodesc_len = 80; 290 ctx->cfg.max_repodesc_len = 80;
287 ctx->cfg.max_blob_size = 0; 291 ctx->cfg.max_blob_size = 0;
288 ctx->cfg.max_stats = 0; 292 ctx->cfg.max_stats = 0;
289 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; 293 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";
290 ctx->cfg.renamelimit = -1; 294 ctx->cfg.renamelimit = -1;
291 ctx->cfg.robots = "index, nofollow"; 295 ctx->cfg.robots = "index, nofollow";
292 ctx->cfg.root_title = "Git repository browser"; 296 ctx->cfg.root_title = "Git repository browser";
293 ctx->cfg.root_desc = "a fast webinterface for the git dscm"; 297 ctx->cfg.root_desc = "a fast webinterface for the git dscm";
294 ctx->cfg.script_name = CGIT_SCRIPT_NAME; 298 ctx->cfg.script_name = CGIT_SCRIPT_NAME;
295 ctx->cfg.section = ""; 299 ctx->cfg.section = "";
296 ctx->cfg.summary_branches = 10; 300 ctx->cfg.summary_branches = 10;
297 ctx->cfg.summary_log = 10; 301 ctx->cfg.summary_log = 10;
298 ctx->cfg.summary_tags = 10; 302 ctx->cfg.summary_tags = 10;
303 ctx->cfg.max_atom_items = 10;
299 ctx->cfg.ssdiff = 0; 304 ctx->cfg.ssdiff = 0;
300 ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG")); 305 ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG"));
301 ctx->env.http_host = xstrdupn(getenv("HTTP_HOST")); 306 ctx->env.http_host = xstrdupn(getenv("HTTP_HOST"));
302 ctx->env.https = xstrdupn(getenv("HTTPS")); 307 ctx->env.https = xstrdupn(getenv("HTTPS"));
303 ctx->env.no_http = xstrdupn(getenv("NO_HTTP")); 308 ctx->env.no_http = xstrdupn(getenv("NO_HTTP"));
304 ctx->env.path_info = xstrdupn(getenv("PATH_INFO")); 309 ctx->env.path_info = xstrdupn(getenv("PATH_INFO"));
305 ctx->env.query_string = xstrdupn(getenv("QUERY_STRING")); 310 ctx->env.query_string = xstrdupn(getenv("QUERY_STRING"));
306 ctx->env.request_method = xstrdupn(getenv("REQUEST_METHOD")); 311 ctx->env.request_method = xstrdupn(getenv("REQUEST_METHOD"));
307 ctx->env.script_name = xstrdupn(getenv("SCRIPT_NAME")); 312 ctx->env.script_name = xstrdupn(getenv("SCRIPT_NAME"));
308 ctx->env.server_name = xstrdupn(getenv("SERVER_NAME")); 313 ctx->env.server_name = xstrdupn(getenv("SERVER_NAME"));
309 ctx->env.server_port = xstrdupn(getenv("SERVER_PORT")); 314 ctx->env.server_port = xstrdupn(getenv("SERVER_PORT"));
310 ctx->page.mimetype = "text/html"; 315 ctx->page.mimetype = "text/html";
311 ctx->page.charset = PAGE_ENCODING; 316 ctx->page.charset = PAGE_ENCODING;
312 ctx->page.filename = NULL; 317 ctx->page.filename = NULL;
313 ctx->page.size = 0; 318 ctx->page.size = 0;
314 ctx->page.modified = time(NULL); 319 ctx->page.modified = time(NULL);
315 ctx->page.expires = ctx->page.modified; 320 ctx->page.expires = ctx->page.modified;
316 ctx->page.etag = NULL; 321 ctx->page.etag = NULL;
317 memset(&ctx->cfg.mimetypes, 0, sizeof(struct string_list)); 322 memset(&ctx->cfg.mimetypes, 0, sizeof(struct string_list));
318 if (ctx->env.script_name) 323 if (ctx->env.script_name)
319 ctx->cfg.script_name = ctx->env.script_name; 324 ctx->cfg.script_name = ctx->env.script_name;
320 if (ctx->env.query_string) 325 if (ctx->env.query_string)
321 ctx->qry.raw = ctx->env.query_string; 326 ctx->qry.raw = ctx->env.query_string;
322 if (!ctx->env.cgit_config) 327 if (!ctx->env.cgit_config)
323 ctx->env.cgit_config = CGIT_CONFIG; 328 ctx->env.cgit_config = CGIT_CONFIG;
324} 329}
325 330
326struct refmatch { 331struct refmatch {
327 char *req_ref; 332 char *req_ref;
328 char *first_ref; 333 char *first_ref;
329 int match; 334 int match;
330}; 335};
331 336
332int find_current_ref(const char *refname, const unsigned char *sha1, 337int find_current_ref(const char *refname, const unsigned char *sha1,
333 int flags, void *cb_data) 338 int flags, void *cb_data)
334{ 339{
335 struct refmatch *info; 340 struct refmatch *info;
336 341
337 info = (struct refmatch *)cb_data; 342 info = (struct refmatch *)cb_data;
338 if (!strcmp(refname, info->req_ref)) 343 if (!strcmp(refname, info->req_ref))
339 info->match = 1; 344 info->match = 1;
340 if (!info->first_ref) 345 if (!info->first_ref)
341 info->first_ref = xstrdup(refname); 346 info->first_ref = xstrdup(refname);
342 return info->match; 347 return info->match;
343} 348}
344 349
345char *find_default_branch(struct cgit_repo *repo) 350char *find_default_branch(struct cgit_repo *repo)
346{ 351{
347 struct refmatch info; 352 struct refmatch info;
348 char *ref; 353 char *ref;
349 354
350 info.req_ref = repo->defbranch; 355 info.req_ref = repo->defbranch;
351 info.first_ref = NULL; 356 info.first_ref = NULL;
352 info.match = 0; 357 info.match = 0;
353 for_each_branch_ref(find_current_ref, &info); 358 for_each_branch_ref(find_current_ref, &info);
354 if (info.match) 359 if (info.match)
355 ref = info.req_ref; 360 ref = info.req_ref;
356 else 361 else
357 ref = info.first_ref; 362 ref = info.first_ref;
358 if (ref) 363 if (ref)
359 ref = xstrdup(ref); 364 ref = xstrdup(ref);
360 return ref; 365 return ref;
361} 366}
362 367
363static int prepare_repo_cmd(struct cgit_context *ctx) 368static int prepare_repo_cmd(struct cgit_context *ctx)
364{ 369{
365 char *tmp; 370 char *tmp;
366 unsigned char sha1[20]; 371 unsigned char sha1[20];
367 int nongit = 0; 372 int nongit = 0;
368 373
369 setenv("GIT_DIR", ctx->repo->path, 1); 374 setenv("GIT_DIR", ctx->repo->path, 1);
370 setup_git_directory_gently(&nongit); 375 setup_git_directory_gently(&nongit);
371 if (nongit) { 376 if (nongit) {
372 ctx->page.title = fmt("%s - %s", ctx->cfg.root_title, 377 ctx->page.title = fmt("%s - %s", ctx->cfg.root_title,
373 "config error"); 378 "config error");
374 tmp = fmt("Not a git repository: '%s'", ctx->repo->path); 379 tmp = fmt("Not a git repository: '%s'", ctx->repo->path);
375 ctx->repo = NULL; 380 ctx->repo = NULL;
376 cgit_print_http_headers(ctx); 381 cgit_print_http_headers(ctx);
377 cgit_print_docstart(ctx); 382 cgit_print_docstart(ctx);
378 cgit_print_pageheader(ctx); 383 cgit_print_pageheader(ctx);
379 cgit_print_error(tmp); 384 cgit_print_error(tmp);
380 cgit_print_docend(); 385 cgit_print_docend();
381 return 1; 386 return 1;
382 } 387 }
383 ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc); 388 ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc);
384 389
385 if (!ctx->qry.head) { 390 if (!ctx->qry.head) {
386 ctx->qry.nohead = 1; 391 ctx->qry.nohead = 1;
387 ctx->qry.head = find_default_branch(ctx->repo); 392 ctx->qry.head = find_default_branch(ctx->repo);
388 ctx->repo->defbranch = ctx->qry.head; 393 ctx->repo->defbranch = ctx->qry.head;
389 } 394 }
390 395
391 if (!ctx->qry.head) { 396 if (!ctx->qry.head) {
392 cgit_print_http_headers(ctx); 397 cgit_print_http_headers(ctx);
393 cgit_print_docstart(ctx); 398 cgit_print_docstart(ctx);
394 cgit_print_pageheader(ctx); 399 cgit_print_pageheader(ctx);
395 cgit_print_error("Repository seems to be empty"); 400 cgit_print_error("Repository seems to be empty");
396 cgit_print_docend(); 401 cgit_print_docend();
397 return 1; 402 return 1;
398 } 403 }
399 404
400 if (get_sha1(ctx->qry.head, sha1)) { 405 if (get_sha1(ctx->qry.head, sha1)) {
401 tmp = xstrdup(ctx->qry.head); 406 tmp = xstrdup(ctx->qry.head);
402 ctx->qry.head = ctx->repo->defbranch; 407 ctx->qry.head = ctx->repo->defbranch;
403 ctx->page.status = 404; 408 ctx->page.status = 404;
404 ctx->page.statusmsg = "not found"; 409 ctx->page.statusmsg = "not found";
405 cgit_print_http_headers(ctx); 410 cgit_print_http_headers(ctx);
406 cgit_print_docstart(ctx); 411 cgit_print_docstart(ctx);
407 cgit_print_pageheader(ctx); 412 cgit_print_pageheader(ctx);
408 cgit_print_error(fmt("Invalid branch: %s", tmp)); 413 cgit_print_error(fmt("Invalid branch: %s", tmp));
409 cgit_print_docend(); 414 cgit_print_docend();
410 return 1; 415 return 1;
411 } 416 }
412 return 0; 417 return 0;
413} 418}
414 419
415static void process_request(void *cbdata) 420static void process_request(void *cbdata)
416{ 421{
417 struct cgit_context *ctx = cbdata; 422 struct cgit_context *ctx = cbdata;
418 struct cgit_cmd *cmd; 423 struct cgit_cmd *cmd;
419 424
420 cmd = cgit_get_cmd(ctx); 425 cmd = cgit_get_cmd(ctx);
421 if (!cmd) { 426 if (!cmd) {
422 ctx->page.title = "cgit error"; 427 ctx->page.title = "cgit error";
423 cgit_print_http_headers(ctx); 428 cgit_print_http_headers(ctx);
424 cgit_print_docstart(ctx); 429 cgit_print_docstart(ctx);
425 cgit_print_pageheader(ctx); 430 cgit_print_pageheader(ctx);
426 cgit_print_error("Invalid request"); 431 cgit_print_error("Invalid request");
427 cgit_print_docend(); 432 cgit_print_docend();
428 return; 433 return;
429 } 434 }
430 435
431 if (cmd->want_repo && !ctx->repo) { 436 if (cmd->want_repo && !ctx->repo) {
432 cgit_print_http_headers(ctx); 437 cgit_print_http_headers(ctx);
433 cgit_print_docstart(ctx); 438 cgit_print_docstart(ctx);
434 cgit_print_pageheader(ctx); 439 cgit_print_pageheader(ctx);
435 cgit_print_error(fmt("No repository selected")); 440 cgit_print_error(fmt("No repository selected"));
436 cgit_print_docend(); 441 cgit_print_docend();
437 return; 442 return;
438 } 443 }
439 444
440 if (ctx->repo && prepare_repo_cmd(ctx)) 445 if (ctx->repo && prepare_repo_cmd(ctx))
441 return; 446 return;
442 447
443 if (cmd->want_layout) { 448 if (cmd->want_layout) {
444 cgit_print_http_headers(ctx); 449 cgit_print_http_headers(ctx);
445 cgit_print_docstart(ctx); 450 cgit_print_docstart(ctx);
446 cgit_print_pageheader(ctx); 451 cgit_print_pageheader(ctx);
447 } 452 }
448 453
449 cmd->fn(ctx); 454 cmd->fn(ctx);
450 455
451 if (cmd->want_layout) 456 if (cmd->want_layout)
452 cgit_print_docend(); 457 cgit_print_docend();
453} 458}
454 459
455int cmp_repos(const void *a, const void *b) 460int cmp_repos(const void *a, const void *b)
456{ 461{
457 const struct cgit_repo *ra = a, *rb = b; 462 const struct cgit_repo *ra = a, *rb = b;
458 return strcmp(ra->url, rb->url); 463 return strcmp(ra->url, rb->url);
459} 464}
460 465
461char *build_snapshot_setting(int bitmap) 466char *build_snapshot_setting(int bitmap)
462{ 467{
463 const struct cgit_snapshot_format *f; 468 const struct cgit_snapshot_format *f;
464 char *result = xstrdup(""); 469 char *result = xstrdup("");
465 char *tmp; 470 char *tmp;
466 int len; 471 int len;
467 472
468 for (f = cgit_snapshot_formats; f->suffix; f++) { 473 for (f = cgit_snapshot_formats; f->suffix; f++) {
469 if (f->bit & bitmap) { 474 if (f->bit & bitmap) {
470 tmp = result; 475 tmp = result;
471 result = xstrdup(fmt("%s%s ", tmp, f->suffix)); 476 result = xstrdup(fmt("%s%s ", tmp, f->suffix));
472 free(tmp); 477 free(tmp);
473 } 478 }
474 } 479 }
475 len = strlen(result); 480 len = strlen(result);
476 if (len) 481 if (len)
477 result[len - 1] = '\0'; 482 result[len - 1] = '\0';
478 return result; 483 return result;
479} 484}
480 485
481char *get_first_line(char *txt) 486char *get_first_line(char *txt)
482{ 487{
483 char *t = xstrdup(txt); 488 char *t = xstrdup(txt);
484 char *p = strchr(t, '\n'); 489 char *p = strchr(t, '\n');
485 if (p) 490 if (p)
486 *p = '\0'; 491 *p = '\0';
487 return t; 492 return t;
488} 493}
489 494
490void print_repo(FILE *f, struct cgit_repo *repo) 495void print_repo(FILE *f, struct cgit_repo *repo)
diff --git a/cgit.h b/cgit.h
index 9b1e3f8..8884f9e 100644
--- a/cgit.h
+++ b/cgit.h
@@ -1,301 +1,303 @@
1#ifndef CGIT_H 1#ifndef CGIT_H
2#define CGIT_H 2#define CGIT_H
3 3
4 4
5#include <git-compat-util.h> 5#include <git-compat-util.h>
6#include <cache.h> 6#include <cache.h>
7#include <grep.h> 7#include <grep.h>
8#include <object.h> 8#include <object.h>
9#include <tree.h> 9#include <tree.h>
10#include <commit.h> 10#include <commit.h>
11#include <tag.h> 11#include <tag.h>
12#include <diff.h> 12#include <diff.h>
13#include <diffcore.h> 13#include <diffcore.h>
14#include <refs.h> 14#include <refs.h>
15#include <revision.h> 15#include <revision.h>
16#include <log-tree.h> 16#include <log-tree.h>
17#include <archive.h> 17#include <archive.h>
18#include <string-list.h> 18#include <string-list.h>
19#include <xdiff-interface.h> 19#include <xdiff-interface.h>
20#include <xdiff/xdiff.h> 20#include <xdiff/xdiff.h>
21#include <utf8.h> 21#include <utf8.h>
22 22
23 23
24/* 24/*
25 * Dateformats used on misc. pages 25 * Dateformats used on misc. pages
26 */ 26 */
27#define FMT_LONGDATE "%Y-%m-%d %H:%M:%S (%Z)" 27#define FMT_LONGDATE "%Y-%m-%d %H:%M:%S (%Z)"
28#define FMT_SHORTDATE "%Y-%m-%d" 28#define FMT_SHORTDATE "%Y-%m-%d"
29#define FMT_ATOMDATE "%Y-%m-%dT%H:%M:%SZ" 29#define FMT_ATOMDATE "%Y-%m-%dT%H:%M:%SZ"
30 30
31 31
32/* 32/*
33 * Limits used for relative dates 33 * Limits used for relative dates
34 */ 34 */
35#define TM_MIN 60 35#define TM_MIN 60
36#define TM_HOUR (TM_MIN * 60) 36#define TM_HOUR (TM_MIN * 60)
37#define TM_DAY (TM_HOUR * 24) 37#define TM_DAY (TM_HOUR * 24)
38#define TM_WEEK (TM_DAY * 7) 38#define TM_WEEK (TM_DAY * 7)
39#define TM_YEAR (TM_DAY * 365) 39#define TM_YEAR (TM_DAY * 365)
40#define TM_MONTH (TM_YEAR / 12.0) 40#define TM_MONTH (TM_YEAR / 12.0)
41 41
42 42
43/* 43/*
44 * Default encoding 44 * Default encoding
45 */ 45 */
46#define PAGE_ENCODING "UTF-8" 46#define PAGE_ENCODING "UTF-8"
47 47
48typedef void (*configfn)(const char *name, const char *value); 48typedef void (*configfn)(const char *name, const char *value);
49typedef void (*filepair_fn)(struct diff_filepair *pair); 49typedef void (*filepair_fn)(struct diff_filepair *pair);
50typedef void (*linediff_fn)(char *line, int len); 50typedef void (*linediff_fn)(char *line, int len);
51 51
52struct cgit_filter { 52struct cgit_filter {
53 char *cmd; 53 char *cmd;
54 char **argv; 54 char **argv;
55 int old_stdout; 55 int old_stdout;
56 int pipe_fh[2]; 56 int pipe_fh[2];
57 int pid; 57 int pid;
58 int exitstatus; 58 int exitstatus;
59}; 59};
60 60
61struct cgit_repo { 61struct cgit_repo {
62 char *url; 62 char *url;
63 char *name; 63 char *name;
64 char *path; 64 char *path;
65 char *desc; 65 char *desc;
66 char *owner; 66 char *owner;
67 char *defbranch; 67 char *defbranch;
68 char *module_link; 68 char *module_link;
69 char *readme; 69 char *readme;
70 char *section; 70 char *section;
71 char *clone_url; 71 char *clone_url;
72 int snapshots; 72 int snapshots;
73 int enable_log_filecount; 73 int enable_log_filecount;
74 int enable_log_linecount; 74 int enable_log_linecount;
75 int enable_remote_branches; 75 int enable_remote_branches;
76 int enable_subject_links; 76 int enable_subject_links;
77 int max_stats; 77 int max_stats;
78 time_t mtime; 78 time_t mtime;
79 struct cgit_filter *about_filter; 79 struct cgit_filter *about_filter;
80 struct cgit_filter *commit_filter; 80 struct cgit_filter *commit_filter;
81 struct cgit_filter *source_filter; 81 struct cgit_filter *source_filter;
82}; 82};
83 83
84typedef void (*repo_config_fn)(struct cgit_repo *repo, const char *name, 84typedef void (*repo_config_fn)(struct cgit_repo *repo, const char *name,
85 const char *value); 85 const char *value);
86 86
87struct cgit_repolist { 87struct cgit_repolist {
88 int length; 88 int length;
89 int count; 89 int count;
90 struct cgit_repo *repos; 90 struct cgit_repo *repos;
91}; 91};
92 92
93struct commitinfo { 93struct commitinfo {
94 struct commit *commit; 94 struct commit *commit;
95 char *author; 95 char *author;
96 char *author_email; 96 char *author_email;
97 unsigned long author_date; 97 unsigned long author_date;
98 char *committer; 98 char *committer;
99 char *committer_email; 99 char *committer_email;
100 unsigned long committer_date; 100 unsigned long committer_date;
101 char *subject; 101 char *subject;
102 char *msg; 102 char *msg;
103 char *msg_encoding; 103 char *msg_encoding;
104}; 104};
105 105
106struct taginfo { 106struct taginfo {
107 char *tagger; 107 char *tagger;
108 char *tagger_email; 108 char *tagger_email;
109 unsigned long tagger_date; 109 unsigned long tagger_date;
110 char *msg; 110 char *msg;
111}; 111};
112 112
113struct refinfo { 113struct refinfo {
114 const char *refname; 114 const char *refname;
115 struct object *object; 115 struct object *object;
116 union { 116 union {
117 struct taginfo *tag; 117 struct taginfo *tag;
118 struct commitinfo *commit; 118 struct commitinfo *commit;
119 }; 119 };
120}; 120};
121 121
122struct reflist { 122struct reflist {
123 struct refinfo **refs; 123 struct refinfo **refs;
124 int alloc; 124 int alloc;
125 int count; 125 int count;
126}; 126};
127 127
128struct cgit_query { 128struct cgit_query {
129 int has_symref; 129 int has_symref;
130 int has_sha1; 130 int has_sha1;
131 char *raw; 131 char *raw;
132 char *repo; 132 char *repo;
133 char *page; 133 char *page;
134 char *search; 134 char *search;
135 char *grep; 135 char *grep;
136 char *head; 136 char *head;
137 char *sha1; 137 char *sha1;
138 char *sha2; 138 char *sha2;
139 char *path; 139 char *path;
140 char *name; 140 char *name;
141 char *mimetype; 141 char *mimetype;
142 char *url; 142 char *url;
143 char *period; 143 char *period;
144 int ofs; 144 int ofs;
145 int nohead; 145 int nohead;
146 char *sort; 146 char *sort;
147 int showmsg; 147 int showmsg;
148 int ssdiff; 148 int ssdiff;
149 int show_all;
149}; 150};
150 151
151struct cgit_config { 152struct cgit_config {
152 char *agefile; 153 char *agefile;
153 char *cache_root; 154 char *cache_root;
154 char *clone_prefix; 155 char *clone_prefix;
155 char *css; 156 char *css;
156 char *favicon; 157 char *favicon;
157 char *footer; 158 char *footer;
158 char *head_include; 159 char *head_include;
159 char *header; 160 char *header;
160 char *index_header; 161 char *index_header;
161 char *index_info; 162 char *index_info;
162 char *logo; 163 char *logo;
163 char *logo_link; 164 char *logo_link;
164 char *module_link; 165 char *module_link;
165 char *robots; 166 char *robots;
166 char *root_title; 167 char *root_title;
167 char *root_desc; 168 char *root_desc;
168 char *root_readme; 169 char *root_readme;
169 char *script_name; 170 char *script_name;
170 char *section; 171 char *section;
171 char *virtual_root; 172 char *virtual_root;
172 int cache_size; 173 int cache_size;
173 int cache_dynamic_ttl; 174 int cache_dynamic_ttl;
174 int cache_max_create_time; 175 int cache_max_create_time;
175 int cache_repo_ttl; 176 int cache_repo_ttl;
176 int cache_root_ttl; 177 int cache_root_ttl;
177 int cache_scanrc_ttl; 178 int cache_scanrc_ttl;
178 int cache_static_ttl; 179 int cache_static_ttl;
179 int embedded; 180 int embedded;
180 int enable_filter_overrides; 181 int enable_filter_overrides;
181 int enable_index_links; 182 int enable_index_links;
182 int enable_log_filecount; 183 int enable_log_filecount;
183 int enable_log_linecount; 184 int enable_log_linecount;
184 int enable_remote_branches; 185 int enable_remote_branches;
185 int enable_subject_links; 186 int enable_subject_links;
186 int enable_tree_linenumbers; 187 int enable_tree_linenumbers;
187 int local_time; 188 int local_time;
189 int max_atom_items;
188 int max_repo_count; 190 int max_repo_count;
189 int max_commit_count; 191 int max_commit_count;
190 int max_lock_attempts; 192 int max_lock_attempts;
191 int max_msg_len; 193 int max_msg_len;
192 int max_repodesc_len; 194 int max_repodesc_len;
193 int max_blob_size; 195 int max_blob_size;
194 int max_stats; 196 int max_stats;
195 int nocache; 197 int nocache;
196 int noplainemail; 198 int noplainemail;
197 int noheader; 199 int noheader;
198 int renamelimit; 200 int renamelimit;
199 int snapshots; 201 int snapshots;
200 int summary_branches; 202 int summary_branches;
201 int summary_log; 203 int summary_log;
202 int summary_tags; 204 int summary_tags;
203 int ssdiff; 205 int ssdiff;
204 struct string_list mimetypes; 206 struct string_list mimetypes;
205 struct cgit_filter *about_filter; 207 struct cgit_filter *about_filter;
206 struct cgit_filter *commit_filter; 208 struct cgit_filter *commit_filter;
207 struct cgit_filter *source_filter; 209 struct cgit_filter *source_filter;
208}; 210};
209 211
210struct cgit_page { 212struct cgit_page {
211 time_t modified; 213 time_t modified;
212 time_t expires; 214 time_t expires;
213 size_t size; 215 size_t size;
214 char *mimetype; 216 char *mimetype;
215 char *charset; 217 char *charset;
216 char *filename; 218 char *filename;
217 char *etag; 219 char *etag;
218 char *title; 220 char *title;
219 int status; 221 int status;
220 char *statusmsg; 222 char *statusmsg;
221}; 223};
222 224
223struct cgit_environment { 225struct cgit_environment {
224 char *cgit_config; 226 char *cgit_config;
225 char *http_host; 227 char *http_host;
226 char *https; 228 char *https;
227 char *no_http; 229 char *no_http;
228 char *path_info; 230 char *path_info;
229 char *query_string; 231 char *query_string;
230 char *request_method; 232 char *request_method;
231 char *script_name; 233 char *script_name;
232 char *server_name; 234 char *server_name;
233 char *server_port; 235 char *server_port;
234}; 236};
235 237
236struct cgit_context { 238struct cgit_context {
237 struct cgit_environment env; 239 struct cgit_environment env;
238 struct cgit_query qry; 240 struct cgit_query qry;
239 struct cgit_config cfg; 241 struct cgit_config cfg;
240 struct cgit_repo *repo; 242 struct cgit_repo *repo;
241 struct cgit_page page; 243 struct cgit_page page;
242}; 244};
243 245
244struct cgit_snapshot_format { 246struct cgit_snapshot_format {
245 const char *suffix; 247 const char *suffix;
246 const char *mimetype; 248 const char *mimetype;
247 write_archive_fn_t write_func; 249 write_archive_fn_t write_func;
248 int bit; 250 int bit;
249}; 251};
250 252
251extern const char *cgit_version; 253extern const char *cgit_version;
252 254
253extern struct cgit_repolist cgit_repolist; 255extern struct cgit_repolist cgit_repolist;
254extern struct cgit_context ctx; 256extern struct cgit_context ctx;
255extern const struct cgit_snapshot_format cgit_snapshot_formats[]; 257extern const struct cgit_snapshot_format cgit_snapshot_formats[];
256 258
257extern struct cgit_repo *cgit_add_repo(const char *url); 259extern struct cgit_repo *cgit_add_repo(const char *url);
258extern struct cgit_repo *cgit_get_repoinfo(const char *url); 260extern struct cgit_repo *cgit_get_repoinfo(const char *url);
259extern void cgit_repo_config_cb(const char *name, const char *value); 261extern void cgit_repo_config_cb(const char *name, const char *value);
260 262
261extern int chk_zero(int result, char *msg); 263extern int chk_zero(int result, char *msg);
262extern int chk_positive(int result, char *msg); 264extern int chk_positive(int result, char *msg);
263extern int chk_non_negative(int result, char *msg); 265extern int chk_non_negative(int result, char *msg);
264 266
265extern char *trim_end(const char *str, char c); 267extern char *trim_end(const char *str, char c);
266extern char *strlpart(char *txt, int maxlen); 268extern char *strlpart(char *txt, int maxlen);
267extern char *strrpart(char *txt, int maxlen); 269extern char *strrpart(char *txt, int maxlen);
268 270
269extern void cgit_add_ref(struct reflist *list, struct refinfo *ref); 271extern void cgit_add_ref(struct reflist *list, struct refinfo *ref);
270extern int cgit_refs_cb(const char *refname, const unsigned char *sha1, 272extern int cgit_refs_cb(const char *refname, const unsigned char *sha1,
271 int flags, void *cb_data); 273 int flags, void *cb_data);
272 274
273extern void *cgit_free_commitinfo(struct commitinfo *info); 275extern void *cgit_free_commitinfo(struct commitinfo *info);
274 276
275extern int cgit_diff_files(const unsigned char *old_sha1, 277extern int cgit_diff_files(const unsigned char *old_sha1,
276 const unsigned char *new_sha1, 278 const unsigned char *new_sha1,
277 unsigned long *old_size, unsigned long *new_size, 279 unsigned long *old_size, unsigned long *new_size,
278 int *binary, linediff_fn fn); 280 int *binary, linediff_fn fn);
279 281
280extern void cgit_diff_tree(const unsigned char *old_sha1, 282extern void cgit_diff_tree(const unsigned char *old_sha1,
281 const unsigned char *new_sha1, 283 const unsigned char *new_sha1,
282 filepair_fn fn, const char *prefix); 284 filepair_fn fn, const char *prefix);
283 285
284extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); 286extern void cgit_diff_commit(struct commit *commit, filepair_fn fn);
285 287
286extern char *fmt(const char *format,...); 288extern char *fmt(const char *format,...);
287 289
288extern struct commitinfo *cgit_parse_commit(struct commit *commit); 290extern struct commitinfo *cgit_parse_commit(struct commit *commit);
289extern struct taginfo *cgit_parse_tag(struct tag *tag); 291extern struct taginfo *cgit_parse_tag(struct tag *tag);
290extern void cgit_parse_url(const char *url); 292extern void cgit_parse_url(const char *url);
291 293
292extern const char *cgit_repobasename(const char *reponame); 294extern const char *cgit_repobasename(const char *reponame);
293 295
294extern int cgit_parse_snapshots_mask(const char *str); 296extern int cgit_parse_snapshots_mask(const char *str);
295 297
296extern int cgit_open_filter(struct cgit_filter *filter); 298extern int cgit_open_filter(struct cgit_filter *filter);
297extern int cgit_close_filter(struct cgit_filter *filter); 299extern int cgit_close_filter(struct cgit_filter *filter);
298 300
299extern int readfile(const char *path, char **buf, size_t *size); 301extern int readfile(const char *path, char **buf, size_t *size);
300 302
301#endif /* CGIT_H */ 303#endif /* CGIT_H */
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index fcd4308..5c24381 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -1,366 +1,370 @@
1:man source: cgit 1:man source: cgit
2:man manual: cgit 2:man manual: cgit
3 3
4CGITRC(5) 4CGITRC(5)
5======== 5========
6 6
7 7
8NAME 8NAME
9---- 9----
10cgitrc - runtime configuration for cgit 10cgitrc - runtime configuration for cgit
11 11
12 12
13SYNOPSIS 13SYNOPSIS
14-------- 14--------
15Cgitrc contains all runtime settings for cgit, including the list of git 15Cgitrc contains all runtime settings for cgit, including the list of git
16repositories, formatted as a line-separated list of NAME=VALUE pairs. Blank 16repositories, formatted as a line-separated list of NAME=VALUE pairs. Blank
17lines, and lines starting with '#', are ignored. 17lines, and lines starting with '#', are ignored.
18 18
19 19
20LOCATION 20LOCATION
21-------- 21--------
22The default location of cgitrc, defined at compile time, is /etc/cgitrc. At 22The default location of cgitrc, defined at compile time, is /etc/cgitrc. At
23runtime, cgit will consult the environment variable CGIT_CONFIG and, if 23runtime, cgit will consult the environment variable CGIT_CONFIG and, if
24defined, use its value instead. 24defined, use its value instead.
25 25
26 26
27GLOBAL SETTINGS 27GLOBAL SETTINGS
28--------------- 28---------------
29about-filter:: 29about-filter::
30 Specifies a command which will be invoked to format the content of 30 Specifies a command which will be invoked to format the content of
31 about pages (both top-level and for each repository). The command will 31 about pages (both top-level and for each repository). The command will
32 get the content of the about-file on its STDIN, and the STDOUT from the 32 get the content of the about-file on its STDIN, and the STDOUT from the
33 command will be included verbatim on the about page. Default value: 33 command will be included verbatim on the about page. Default value:
34 none. 34 none.
35 35
36agefile:: 36agefile::
37 Specifies a path, relative to each repository path, which can be used 37 Specifies a path, relative to each repository path, which can be used
38 to specify the date and time of the youngest commit in the repository. 38 to specify the date and time of the youngest commit in the repository.
39 The first line in the file is used as input to the "parse_date" 39 The first line in the file is used as input to the "parse_date"
40 function in libgit. Recommended timestamp-format is "yyyy-mm-dd 40 function in libgit. Recommended timestamp-format is "yyyy-mm-dd
41 hh:mm:ss". Default value: "info/web/last-modified". 41 hh:mm:ss". Default value: "info/web/last-modified".
42 42
43cache-root:: 43cache-root::
44 Path used to store the cgit cache entries. Default value: 44 Path used to store the cgit cache entries. Default value:
45 "/var/cache/cgit". 45 "/var/cache/cgit".
46 46
47cache-dynamic-ttl:: 47cache-dynamic-ttl::
48 Number which specifies the time-to-live, in minutes, for the cached 48 Number which specifies the time-to-live, in minutes, for the cached
49 version of repository pages accessed without a fixed SHA1. Default 49 version of repository pages accessed without a fixed SHA1. Default
50 value: "5". 50 value: "5".
51 51
52cache-repo-ttl:: 52cache-repo-ttl::
53 Number which specifies the time-to-live, in minutes, for the cached 53 Number which specifies the time-to-live, in minutes, for the cached
54 version of the repository summary page. Default value: "5". 54 version of the repository summary page. Default value: "5".
55 55
56cache-root-ttl:: 56cache-root-ttl::
57 Number which specifies the time-to-live, in minutes, for the cached 57 Number which specifies the time-to-live, in minutes, for the cached
58 version of the repository index page. Default value: "5". 58 version of the repository index page. Default value: "5".
59 59
60cache-scanrc-ttl:: 60cache-scanrc-ttl::
61 Number which specifies the time-to-live, in minutes, for the result 61 Number which specifies the time-to-live, in minutes, for the result
62 of scanning a path for git repositories. Default value: "15". 62 of scanning a path for git repositories. Default value: "15".
63 63
64cache-size:: 64cache-size::
65 The maximum number of entries in the cgit cache. Default value: "0" 65 The maximum number of entries in the cgit cache. Default value: "0"
66 (i.e. caching is disabled). 66 (i.e. caching is disabled).
67 67
68cache-static-ttl:: 68cache-static-ttl::
69 Number which specifies the time-to-live, in minutes, for the cached 69 Number which specifies the time-to-live, in minutes, for the cached
70 version of repository pages accessed with a fixed SHA1. Default value: 70 version of repository pages accessed with a fixed SHA1. Default value:
71 "5". 71 "5".
72 72
73clone-prefix:: 73clone-prefix::
74 Space-separated list of common prefixes which, when combined with a 74 Space-separated list of common prefixes which, when combined with a
75 repository url, generates valid clone urls for the repository. This 75 repository url, generates valid clone urls for the repository. This
76 setting is only used if `repo.clone-url` is unspecified. Default value: 76 setting is only used if `repo.clone-url` is unspecified. Default value:
77 none. 77 none.
78 78
79commit-filter:: 79commit-filter::
80 Specifies a command which will be invoked to format commit messages. 80 Specifies a command which will be invoked to format commit messages.
81 The command will get the message on its STDIN, and the STDOUT from the 81 The command will get the message on its STDIN, and the STDOUT from the
82 command will be included verbatim as the commit message, i.e. this can 82 command will be included verbatim as the commit message, i.e. this can
83 be used to implement bugtracker integration. Default value: none. 83 be used to implement bugtracker integration. Default value: none.
84 84
85css:: 85css::
86 Url which specifies the css document to include in all cgit pages. 86 Url which specifies the css document to include in all cgit pages.
87 Default value: "/cgit.css". 87 Default value: "/cgit.css".
88 88
89embedded:: 89embedded::
90 Flag which, when set to "1", will make cgit generate a html fragment 90 Flag which, when set to "1", will make cgit generate a html fragment
91 suitable for embedding in other html pages. Default value: none. See 91 suitable for embedding in other html pages. Default value: none. See
92 also: "noheader". 92 also: "noheader".
93 93
94enable-filter-overrides:: 94enable-filter-overrides::
95 Flag which, when set to "1", allows all filter settings to be 95 Flag which, when set to "1", allows all filter settings to be
96 overridden in repository-specific cgitrc files. Default value: none. 96 overridden in repository-specific cgitrc files. Default value: none.
97 97
98enable-index-links:: 98enable-index-links::
99 Flag which, when set to "1", will make cgit generate extra links for 99 Flag which, when set to "1", will make cgit generate extra links for
100 each repo in the repository index (specifically, to the "summary", 100 each repo in the repository index (specifically, to the "summary",
101 "commit" and "tree" pages). Default value: "0". 101 "commit" and "tree" pages). Default value: "0".
102 102
103enable-log-filecount:: 103enable-log-filecount::
104 Flag which, when set to "1", will make cgit print the number of 104 Flag which, when set to "1", will make cgit print the number of
105 modified files for each commit on the repository log page. Default 105 modified files for each commit on the repository log page. Default
106 value: "0". 106 value: "0".
107 107
108enable-log-linecount:: 108enable-log-linecount::
109 Flag which, when set to "1", will make cgit print the number of added 109 Flag which, when set to "1", will make cgit print the number of added
110 and removed lines for each commit on the repository log page. Default 110 and removed lines for each commit on the repository log page. Default
111 value: "0". 111 value: "0".
112 112
113enable-remote-branches:: 113enable-remote-branches::
114 Flag which, when set to "1", will make cgit display remote branches 114 Flag which, when set to "1", will make cgit display remote branches
115 in the summary and refs views. Default value: "0". See also: 115 in the summary and refs views. Default value: "0". See also:
116 "repo.enable-remote-branches". 116 "repo.enable-remote-branches".
117 117
118enable-subject-links:: 118enable-subject-links::
119 Flag which, when set to "1", will make cgit use the subject of the 119 Flag which, when set to "1", will make cgit use the subject of the
120 parent commit as link text when generating links to parent commits 120 parent commit as link text when generating links to parent commits
121 in commit view. Default value: "0". See also: 121 in commit view. Default value: "0". See also:
122 "repo.enable-subject-links". 122 "repo.enable-subject-links".
123 123
124enable-tree-linenumbers:: 124enable-tree-linenumbers::
125 Flag which, when set to "1", will make cgit generate linenumber links 125 Flag which, when set to "1", will make cgit generate linenumber links
126 for plaintext blobs printed in the tree view. Default value: "1". 126 for plaintext blobs printed in the tree view. Default value: "1".
127 127
128favicon:: 128favicon::
129 Url used as link to a shortcut icon for cgit. If specified, it is 129 Url used as link to a shortcut icon for cgit. If specified, it is
130 suggested to use the value "/favicon.ico" since certain browsers will 130 suggested to use the value "/favicon.ico" since certain browsers will
131 ignore other values. Default value: none. 131 ignore other values. Default value: none.
132 132
133footer:: 133footer::
134 The content of the file specified with this option will be included 134 The content of the file specified with this option will be included
135 verbatim at the bottom of all pages (i.e. it replaces the standard 135 verbatim at the bottom of all pages (i.e. it replaces the standard
136 "generated by..." message. Default value: none. 136 "generated by..." message. Default value: none.
137 137
138head-include:: 138head-include::
139 The content of the file specified with this option will be included 139 The content of the file specified with this option will be included
140 verbatim in the html HEAD section on all pages. Default value: none. 140 verbatim in the html HEAD section on all pages. Default value: none.
141 141
142header:: 142header::
143 The content of the file specified with this option will be included 143 The content of the file specified with this option will be included
144 verbatim at the top of all pages. Default value: none. 144 verbatim at the top of all pages. Default value: none.
145 145
146include:: 146include::
147 Name of a configfile to include before the rest of the current config- 147 Name of a configfile to include before the rest of the current config-
148 file is parsed. Default value: none. 148 file is parsed. Default value: none.
149 149
150index-header:: 150index-header::
151 The content of the file specified with this option will be included 151 The content of the file specified with this option will be included
152 verbatim above the repository index. This setting is deprecated, and 152 verbatim above the repository index. This setting is deprecated, and
153 will not be supported by cgit-1.0 (use root-readme instead). Default 153 will not be supported by cgit-1.0 (use root-readme instead). Default
154 value: none. 154 value: none.
155 155
156index-info:: 156index-info::
157 The content of the file specified with this option will be included 157 The content of the file specified with this option will be included
158 verbatim below the heading on the repository index page. This setting 158 verbatim below the heading on the repository index page. This setting
159 is deprecated, and will not be supported by cgit-1.0 (use root-desc 159 is deprecated, and will not be supported by cgit-1.0 (use root-desc
160 instead). Default value: none. 160 instead). Default value: none.
161 161
162local-time:: 162local-time::
163 Flag which, if set to "1", makes cgit print commit and tag times in the 163 Flag which, if set to "1", makes cgit print commit and tag times in the
164 servers timezone. Default value: "0". 164 servers timezone. Default value: "0".
165 165
166logo:: 166logo::
167 Url which specifies the source of an image which will be used as a logo 167 Url which specifies the source of an image which will be used as a logo
168 on all cgit pages. Default value: "/cgit.png". 168 on all cgit pages. Default value: "/cgit.png".
169 169
170logo-link:: 170logo-link::
171 Url loaded when clicking on the cgit logo image. If unspecified the 171 Url loaded when clicking on the cgit logo image. If unspecified the
172 calculated url of the repository index page will be used. Default 172 calculated url of the repository index page will be used. Default
173 value: none. 173 value: none.
174 174
175max-atom-items::
176 Specifies the number of items to display in atom feeds view. Default
177 value: "10".
178
175max-commit-count:: 179max-commit-count::
176 Specifies the number of entries to list per page in "log" view. Default 180 Specifies the number of entries to list per page in "log" view. Default
177 value: "50". 181 value: "50".
178 182
179max-message-length:: 183max-message-length::
180 Specifies the maximum number of commit message characters to display in 184 Specifies the maximum number of commit message characters to display in
181 "log" view. Default value: "80". 185 "log" view. Default value: "80".
182 186
183max-repo-count:: 187max-repo-count::
184 Specifies the number of entries to list per page on therepository 188 Specifies the number of entries to list per page on therepository
185 index page. Default value: "50". 189 index page. Default value: "50".
186 190
187max-repodesc-length:: 191max-repodesc-length::
188 Specifies the maximum number of repo description characters to display 192 Specifies the maximum number of repo description characters to display
189 on the repository index page. Default value: "80". 193 on the repository index page. Default value: "80".
190 194
191max-blob-size:: 195max-blob-size::
192 Specifies the maximum size of a blob to display HTML for in KBytes. 196 Specifies the maximum size of a blob to display HTML for in KBytes.
193 Default value: "0" (limit disabled). 197 Default value: "0" (limit disabled).
194 198
195max-stats:: 199max-stats::
196 Set the default maximum statistics period. Valid values are "week", 200 Set the default maximum statistics period. Valid values are "week",
197 "month", "quarter" and "year". If unspecified, statistics are 201 "month", "quarter" and "year". If unspecified, statistics are
198 disabled. Default value: none. See also: "repo.max-stats". 202 disabled. Default value: none. See also: "repo.max-stats".
199 203
200mimetype.<ext>:: 204mimetype.<ext>::
201 Set the mimetype for the specified filename extension. This is used 205 Set the mimetype for the specified filename extension. This is used
202 by the `plain` command when returning blob content. 206 by the `plain` command when returning blob content.
203 207
204module-link:: 208module-link::
205 Text which will be used as the formatstring for a hyperlink when a 209 Text which will be used as the formatstring for a hyperlink when a
206 submodule is printed in a directory listing. The arguments for the 210 submodule is printed in a directory listing. The arguments for the
207 formatstring are the path and SHA1 of the submodule commit. Default 211 formatstring are the path and SHA1 of the submodule commit. Default
208 value: "./?repo=%s&page=commit&id=%s" 212 value: "./?repo=%s&page=commit&id=%s"
209 213
210nocache:: 214nocache::
211 If set to the value "1" caching will be disabled. This settings is 215 If set to the value "1" caching will be disabled. This settings is
212 deprecated, and will not be honored starting with cgit-1.0. Default 216 deprecated, and will not be honored starting with cgit-1.0. Default
213 value: "0". 217 value: "0".
214 218
215noplainemail:: 219noplainemail::
216 If set to "1" showing full author email adresses will be disabled. 220 If set to "1" showing full author email adresses will be disabled.
217 Default value: "0". 221 Default value: "0".
218 222
219noheader:: 223noheader::
220 Flag which, when set to "1", will make cgit omit the standard header 224 Flag which, when set to "1", will make cgit omit the standard header
221 on all pages. Default value: none. See also: "embedded". 225 on all pages. Default value: none. See also: "embedded".
222 226
223renamelimit:: 227renamelimit::
224 Maximum number of files to consider when detecting renames. The value 228 Maximum number of files to consider when detecting renames. The value
225 "-1" uses the compiletime value in git (for further info, look at 229 "-1" uses the compiletime value in git (for further info, look at
226 `man git-diff`). Default value: "-1". 230 `man git-diff`). Default value: "-1".
227 231
228repo.group:: 232repo.group::
229 Legacy alias for "section". This option is deprecated and will not be 233 Legacy alias for "section". This option is deprecated and will not be
230 supported in cgit-1.0. 234 supported in cgit-1.0.
231 235
232robots:: 236robots::
233 Text used as content for the "robots" meta-tag. Default value: 237 Text used as content for the "robots" meta-tag. Default value:
234 "index, nofollow". 238 "index, nofollow".
235 239
236root-desc:: 240root-desc::
237 Text printed below the heading on the repository index page. Default 241 Text printed below the heading on the repository index page. Default
238 value: "a fast webinterface for the git dscm". 242 value: "a fast webinterface for the git dscm".
239 243
240root-readme:: 244root-readme::
241 The content of the file specified with this option will be included 245 The content of the file specified with this option will be included
242 verbatim below the "about" link on the repository index page. Default 246 verbatim below the "about" link on the repository index page. Default
243 value: none. 247 value: none.
244 248
245root-title:: 249root-title::
246 Text printed as heading on the repository index page. Default value: 250 Text printed as heading on the repository index page. Default value:
247 "Git Repository Browser". 251 "Git Repository Browser".
248 252
249scan-path:: 253scan-path::
250 A path which will be scanned for repositories. If caching is enabled, 254 A path which will be scanned for repositories. If caching is enabled,
251 the result will be cached as a cgitrc include-file in the cache 255 the result will be cached as a cgitrc include-file in the cache
252 directory. Default value: none. See also: cache-scanrc-ttl. 256 directory. Default value: none. See also: cache-scanrc-ttl.
253 257
254section:: 258section::
255 The name of the current repository section - all repositories defined 259 The name of the current repository section - all repositories defined
256 after this option will inherit the current section name. Default value: 260 after this option will inherit the current section name. Default value:
257 none. 261 none.
258 262
259side-by-side-diffs:: 263side-by-side-diffs::
260 If set to "1" shows side-by-side diffs instead of unidiffs per 264 If set to "1" shows side-by-side diffs instead of unidiffs per
261 default. Default value: "0". 265 default. Default value: "0".
262 266
263snapshots:: 267snapshots::
264 Text which specifies the default set of snapshot formats generated by 268 Text which specifies the default set of snapshot formats generated by
265 cgit. The value is a space-separated list of zero or more of the 269 cgit. The value is a space-separated list of zero or more of the
266 values "tar", "tar.gz", "tar.bz2" and "zip". Default value: none. 270 values "tar", "tar.gz", "tar.bz2" and "zip". Default value: none.
267 271
268source-filter:: 272source-filter::
269 Specifies a command which will be invoked to format plaintext blobs 273 Specifies a command which will be invoked to format plaintext blobs
270 in the tree view. The command will get the blob content on its STDIN 274 in the tree view. The command will get the blob content on its STDIN
271 and the name of the blob as its only command line argument. The STDOUT 275 and the name of the blob as its only command line argument. The STDOUT
272 from the command will be included verbatim as the blob contents, i.e. 276 from the command will be included verbatim as the blob contents, i.e.
273 this can be used to implement e.g. syntax highlighting. Default value: 277 this can be used to implement e.g. syntax highlighting. Default value:
274 none. 278 none.
275 279
276summary-branches:: 280summary-branches::
277 Specifies the number of branches to display in the repository "summary" 281 Specifies the number of branches to display in the repository "summary"
278 view. Default value: "10". 282 view. Default value: "10".
279 283
280summary-log:: 284summary-log::
281 Specifies the number of log entries to display in the repository 285 Specifies the number of log entries to display in the repository
282 "summary" view. Default value: "10". 286 "summary" view. Default value: "10".
283 287
284summary-tags:: 288summary-tags::
285 Specifies the number of tags to display in the repository "summary" 289 Specifies the number of tags to display in the repository "summary"
286 view. Default value: "10". 290 view. Default value: "10".
287 291
288virtual-root:: 292virtual-root::
289 Url which, if specified, will be used as root for all cgit links. It 293 Url which, if specified, will be used as root for all cgit links. It
290 will also cause cgit to generate 'virtual urls', i.e. urls like 294 will also cause cgit to generate 'virtual urls', i.e. urls like
291 '/cgit/tree/README' as opposed to '?r=cgit&p=tree&path=README'. Default 295 '/cgit/tree/README' as opposed to '?r=cgit&p=tree&path=README'. Default
292 value: none. 296 value: none.
293 NOTE: cgit has recently learned how to use PATH_INFO to achieve the 297 NOTE: cgit has recently learned how to use PATH_INFO to achieve the
294 same kind of virtual urls, so this option will probably be deprecated. 298 same kind of virtual urls, so this option will probably be deprecated.
295 299
296REPOSITORY SETTINGS 300REPOSITORY SETTINGS
297------------------- 301-------------------
298repo.about-filter:: 302repo.about-filter::
299 Override the default about-filter. Default value: none. See also: 303 Override the default about-filter. Default value: none. See also:
300 "enable-filter-overrides". 304 "enable-filter-overrides".
301 305
302repo.clone-url:: 306repo.clone-url::
303 A list of space-separated urls which can be used to clone this repo. 307 A list of space-separated urls which can be used to clone this repo.
304 Default value: none. 308 Default value: none.
305 309
306repo.commit-filter:: 310repo.commit-filter::
307 Override the default commit-filter. Default value: none. See also: 311 Override the default commit-filter. Default value: none. See also:
308 "enable-filter-overrides". 312 "enable-filter-overrides".
309 313
310repo.defbranch:: 314repo.defbranch::
311 The name of the default branch for this repository. If no such branch 315 The name of the default branch for this repository. If no such branch
312 exists in the repository, the first branch name (when sorted) is used 316 exists in the repository, the first branch name (when sorted) is used
313 as default instead. Default value: "master". 317 as default instead. Default value: "master".
314 318
315repo.desc:: 319repo.desc::
316 The value to show as repository description. Default value: none. 320 The value to show as repository description. Default value: none.
317 321
318repo.enable-log-filecount:: 322repo.enable-log-filecount::
319 A flag which can be used to disable the global setting 323 A flag which can be used to disable the global setting
320 `enable-log-filecount'. Default value: none. 324 `enable-log-filecount'. Default value: none.
321 325
322repo.enable-log-linecount:: 326repo.enable-log-linecount::
323 A flag which can be used to disable the global setting 327 A flag which can be used to disable the global setting
324 `enable-log-linecount'. Default value: none. 328 `enable-log-linecount'. Default value: none.
325 329
326repo.enable-remote-branches:: 330repo.enable-remote-branches::
327 Flag which, when set to "1", will make cgit display remote branches 331 Flag which, when set to "1", will make cgit display remote branches
328 in the summary and refs views. Default value: <enable-remote-branches>. 332 in the summary and refs views. Default value: <enable-remote-branches>.
329 333
330repo.enable-subject-links:: 334repo.enable-subject-links::
331 A flag which can be used to override the global setting 335 A flag which can be used to override the global setting
332 `enable-subject-links'. Default value: none. 336 `enable-subject-links'. Default value: none.
333 337
334repo.max-stats:: 338repo.max-stats::
335 Override the default maximum statistics period. Valid values are equal 339 Override the default maximum statistics period. Valid values are equal
336 to the values specified for the global "max-stats" setting. Default 340 to the values specified for the global "max-stats" setting. Default
337 value: none. 341 value: none.
338 342
339repo.name:: 343repo.name::
340 The value to show as repository name. Default value: <repo.url>. 344 The value to show as repository name. Default value: <repo.url>.
341 345
342repo.owner:: 346repo.owner::
343 A value used to identify the owner of the repository. Default value: 347 A value used to identify the owner of the repository. Default value:
344 none. 348 none.
345 349
346repo.path:: 350repo.path::
347 An absolute path to the repository directory. For non-bare repositories 351 An absolute path to the repository directory. For non-bare repositories
348 this is the .git-directory. Default value: none. 352 this is the .git-directory. Default value: none.
349 353
350repo.readme:: 354repo.readme::
351 A path (relative to <repo.path>) which specifies a file to include 355 A path (relative to <repo.path>) which specifies a file to include
352 verbatim as the "About" page for this repo. Default value: none. 356 verbatim as the "About" page for this repo. Default value: none.
353 357
354repo.snapshots:: 358repo.snapshots::
355 A mask of allowed snapshot-formats for this repo, restricted by the 359 A mask of allowed snapshot-formats for this repo, restricted by the
356 "snapshots" global setting. Default value: <snapshots>. 360 "snapshots" global setting. Default value: <snapshots>.
357 361
358repo.section:: 362repo.section::
359 Override the current section name for this repository. Default value: 363 Override the current section name for this repository. Default value:
360 none. 364 none.
361 365
362repo.source-filter:: 366repo.source-filter::
363 Override the default source-filter. Default value: none. See also: 367 Override the default source-filter. Default value: none. See also:
364 "enable-filter-overrides". 368 "enable-filter-overrides".
365 369
366repo.url:: 370repo.url::
diff --git a/cmd.c b/cmd.c
index 766f903..ad784fc 100644
--- a/cmd.c
+++ b/cmd.c
@@ -1,171 +1,171 @@
1/* cmd.c: the cgit command dispatcher 1/* cmd.c: the cgit command dispatcher
2 * 2 *
3 * Copyright (C) 2008 Lars Hjemli 3 * Copyright (C) 2008 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 "cmd.h" 10#include "cmd.h"
11#include "cache.h" 11#include "cache.h"
12#include "ui-shared.h" 12#include "ui-shared.h"
13#include "ui-atom.h" 13#include "ui-atom.h"
14#include "ui-blob.h" 14#include "ui-blob.h"
15#include "ui-clone.h" 15#include "ui-clone.h"
16#include "ui-commit.h" 16#include "ui-commit.h"
17#include "ui-diff.h" 17#include "ui-diff.h"
18#include "ui-log.h" 18#include "ui-log.h"
19#include "ui-patch.h" 19#include "ui-patch.h"
20#include "ui-plain.h" 20#include "ui-plain.h"
21#include "ui-refs.h" 21#include "ui-refs.h"
22#include "ui-repolist.h" 22#include "ui-repolist.h"
23#include "ui-snapshot.h" 23#include "ui-snapshot.h"
24#include "ui-stats.h" 24#include "ui-stats.h"
25#include "ui-summary.h" 25#include "ui-summary.h"
26#include "ui-tag.h" 26#include "ui-tag.h"
27#include "ui-tree.h" 27#include "ui-tree.h"
28 28
29static void HEAD_fn(struct cgit_context *ctx) 29static void HEAD_fn(struct cgit_context *ctx)
30{ 30{
31 cgit_clone_head(ctx); 31 cgit_clone_head(ctx);
32} 32}
33 33
34static void atom_fn(struct cgit_context *ctx) 34static void atom_fn(struct cgit_context *ctx)
35{ 35{
36 cgit_print_atom(ctx->qry.head, ctx->qry.path, 10); 36 cgit_print_atom(ctx->qry.head, ctx->qry.path, ctx->cfg.max_atom_items);
37} 37}
38 38
39static void about_fn(struct cgit_context *ctx) 39static void about_fn(struct cgit_context *ctx)
40{ 40{
41 if (ctx->repo) 41 if (ctx->repo)
42 cgit_print_repo_readme(ctx->qry.path); 42 cgit_print_repo_readme(ctx->qry.path);
43 else 43 else
44 cgit_print_site_readme(); 44 cgit_print_site_readme();
45} 45}
46 46
47static void blob_fn(struct cgit_context *ctx) 47static void blob_fn(struct cgit_context *ctx)
48{ 48{
49 cgit_print_blob(ctx->qry.sha1, ctx->qry.path, ctx->qry.head); 49 cgit_print_blob(ctx->qry.sha1, ctx->qry.path, ctx->qry.head);
50} 50}
51 51
52static void commit_fn(struct cgit_context *ctx) 52static void commit_fn(struct cgit_context *ctx)
53{ 53{
54 cgit_print_commit(ctx->qry.sha1); 54 cgit_print_commit(ctx->qry.sha1);
55} 55}
56 56
57static void diff_fn(struct cgit_context *ctx) 57static void diff_fn(struct cgit_context *ctx)
58{ 58{
59 cgit_print_diff(ctx->qry.sha1, ctx->qry.sha2, ctx->qry.path); 59 cgit_print_diff(ctx->qry.sha1, ctx->qry.sha2, ctx->qry.path);
60} 60}
61 61
62static void info_fn(struct cgit_context *ctx) 62static void info_fn(struct cgit_context *ctx)
63{ 63{
64 cgit_clone_info(ctx); 64 cgit_clone_info(ctx);
65} 65}
66 66
67static void log_fn(struct cgit_context *ctx) 67static void log_fn(struct cgit_context *ctx)
68{ 68{
69 cgit_print_log(ctx->qry.sha1, ctx->qry.ofs, ctx->cfg.max_commit_count, 69 cgit_print_log(ctx->qry.sha1, ctx->qry.ofs, ctx->cfg.max_commit_count,
70 ctx->qry.grep, ctx->qry.search, ctx->qry.path, 1); 70 ctx->qry.grep, ctx->qry.search, ctx->qry.path, 1);
71} 71}
72 72
73static void ls_cache_fn(struct cgit_context *ctx) 73static void ls_cache_fn(struct cgit_context *ctx)
74{ 74{
75 ctx->page.mimetype = "text/plain"; 75 ctx->page.mimetype = "text/plain";
76 ctx->page.filename = "ls-cache.txt"; 76 ctx->page.filename = "ls-cache.txt";
77 cgit_print_http_headers(ctx); 77 cgit_print_http_headers(ctx);
78 cache_ls(ctx->cfg.cache_root); 78 cache_ls(ctx->cfg.cache_root);
79} 79}
80 80
81static void objects_fn(struct cgit_context *ctx) 81static void objects_fn(struct cgit_context *ctx)
82{ 82{
83 cgit_clone_objects(ctx); 83 cgit_clone_objects(ctx);
84} 84}
85 85
86static void repolist_fn(struct cgit_context *ctx) 86static void repolist_fn(struct cgit_context *ctx)
87{ 87{
88 cgit_print_repolist(); 88 cgit_print_repolist();
89} 89}
90 90
91static void patch_fn(struct cgit_context *ctx) 91static void patch_fn(struct cgit_context *ctx)
92{ 92{
93 cgit_print_patch(ctx->qry.sha1); 93 cgit_print_patch(ctx->qry.sha1);
94} 94}
95 95
96static void plain_fn(struct cgit_context *ctx) 96static void plain_fn(struct cgit_context *ctx)
97{ 97{
98 cgit_print_plain(ctx); 98 cgit_print_plain(ctx);
99} 99}
100 100
101static void refs_fn(struct cgit_context *ctx) 101static void refs_fn(struct cgit_context *ctx)
102{ 102{
103 cgit_print_refs(); 103 cgit_print_refs();
104} 104}
105 105
106static void snapshot_fn(struct cgit_context *ctx) 106static void snapshot_fn(struct cgit_context *ctx)
107{ 107{
108 cgit_print_snapshot(ctx->qry.head, ctx->qry.sha1, ctx->qry.path, 108 cgit_print_snapshot(ctx->qry.head, ctx->qry.sha1, ctx->qry.path,
109 ctx->repo->snapshots, ctx->qry.nohead); 109 ctx->repo->snapshots, ctx->qry.nohead);
110} 110}
111 111
112static void stats_fn(struct cgit_context *ctx) 112static void stats_fn(struct cgit_context *ctx)
113{ 113{
114 cgit_show_stats(ctx); 114 cgit_show_stats(ctx);
115} 115}
116 116
117static void summary_fn(struct cgit_context *ctx) 117static void summary_fn(struct cgit_context *ctx)
118{ 118{
119 cgit_print_summary(); 119 cgit_print_summary();
120} 120}
121 121
122static void tag_fn(struct cgit_context *ctx) 122static void tag_fn(struct cgit_context *ctx)
123{ 123{
124 cgit_print_tag(ctx->qry.sha1); 124 cgit_print_tag(ctx->qry.sha1);
125} 125}
126 126
127static void tree_fn(struct cgit_context *ctx) 127static void tree_fn(struct cgit_context *ctx)
128{ 128{
129 cgit_print_tree(ctx->qry.sha1, ctx->qry.path); 129 cgit_print_tree(ctx->qry.sha1, ctx->qry.path);
130} 130}
131 131
132#define def_cmd(name, want_repo, want_layout) \ 132#define def_cmd(name, want_repo, want_layout) \
133 {#name, name##_fn, want_repo, want_layout} 133 {#name, name##_fn, want_repo, want_layout}
134 134
135struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx) 135struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx)
136{ 136{
137 static struct cgit_cmd cmds[] = { 137 static struct cgit_cmd cmds[] = {
138 def_cmd(HEAD, 1, 0), 138 def_cmd(HEAD, 1, 0),
139 def_cmd(atom, 1, 0), 139 def_cmd(atom, 1, 0),
140 def_cmd(about, 0, 1), 140 def_cmd(about, 0, 1),
141 def_cmd(blob, 1, 0), 141 def_cmd(blob, 1, 0),
142 def_cmd(commit, 1, 1), 142 def_cmd(commit, 1, 1),
143 def_cmd(diff, 1, 1), 143 def_cmd(diff, 1, 1),
144 def_cmd(info, 1, 0), 144 def_cmd(info, 1, 0),
145 def_cmd(log, 1, 1), 145 def_cmd(log, 1, 1),
146 def_cmd(ls_cache, 0, 0), 146 def_cmd(ls_cache, 0, 0),
147 def_cmd(objects, 1, 0), 147 def_cmd(objects, 1, 0),
148 def_cmd(patch, 1, 0), 148 def_cmd(patch, 1, 0),
149 def_cmd(plain, 1, 0), 149 def_cmd(plain, 1, 0),
150 def_cmd(refs, 1, 1), 150 def_cmd(refs, 1, 1),
151 def_cmd(repolist, 0, 0), 151 def_cmd(repolist, 0, 0),
152 def_cmd(snapshot, 1, 0), 152 def_cmd(snapshot, 1, 0),
153 def_cmd(stats, 1, 1), 153 def_cmd(stats, 1, 1),
154 def_cmd(summary, 1, 1), 154 def_cmd(summary, 1, 1),
155 def_cmd(tag, 1, 1), 155 def_cmd(tag, 1, 1),
156 def_cmd(tree, 1, 1), 156 def_cmd(tree, 1, 1),
157 }; 157 };
158 int i; 158 int i;
159 159
160 if (ctx->qry.page == NULL) { 160 if (ctx->qry.page == NULL) {
161 if (ctx->repo) 161 if (ctx->repo)
162 ctx->qry.page = "summary"; 162 ctx->qry.page = "summary";
163 else 163 else
164 ctx->qry.page = "repolist"; 164 ctx->qry.page = "repolist";
165 } 165 }
166 166
167 for(i = 0; i < sizeof(cmds)/sizeof(*cmds); i++) 167 for(i = 0; i < sizeof(cmds)/sizeof(*cmds); i++)
168 if (!strcmp(ctx->qry.page, cmds[i].name)) 168 if (!strcmp(ctx->qry.page, cmds[i].name))
169 return &cmds[i]; 169 return &cmds[i];
170 return NULL; 170 return NULL;
171} 171}
diff --git a/ui-atom.c b/ui-atom.c
index 808b2d0..9f049ae 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -1,131 +1,133 @@
1/* ui-atom.c: functions for atom feeds 1/* ui-atom.c: functions for atom feeds
2 * 2 *
3 * Copyright (C) 2008 Lars Hjemli 3 * Copyright (C) 2008 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 "html.h" 10#include "html.h"
11#include "ui-shared.h" 11#include "ui-shared.h"
12 12
13void add_entry(struct commit *commit, char *host) 13void add_entry(struct commit *commit, char *host)
14{ 14{
15 char delim = '&'; 15 char delim = '&';
16 char *hex; 16 char *hex;
17 char *mail, *t, *t2; 17 char *mail, *t, *t2;
18 struct commitinfo *info; 18 struct commitinfo *info;
19 19
20 info = cgit_parse_commit(commit); 20 info = cgit_parse_commit(commit);
21 hex = sha1_to_hex(commit->object.sha1); 21 hex = sha1_to_hex(commit->object.sha1);
22 html("<entry>\n"); 22 html("<entry>\n");
23 html("<title>"); 23 html("<title>");
24 html_txt(info->subject); 24 html_txt(info->subject);
25 html("</title>\n"); 25 html("</title>\n");
26 html("<updated>"); 26 html("<updated>");
27 cgit_print_date(info->author_date, FMT_ATOMDATE, ctx.cfg.local_time); 27 cgit_print_date(info->author_date, FMT_ATOMDATE, ctx.cfg.local_time);
28 html("</updated>\n"); 28 html("</updated>\n");
29 html("<author>\n"); 29 html("<author>\n");
30 if (info->author) { 30 if (info->author) {
31 html("<name>"); 31 html("<name>");
32 html_txt(info->author); 32 html_txt(info->author);
33 html("</name>\n"); 33 html("</name>\n");
34 } 34 }
35 if (info->author_email && !ctx.cfg.noplainemail) { 35 if (info->author_email && !ctx.cfg.noplainemail) {
36 mail = xstrdup(info->author_email); 36 mail = xstrdup(info->author_email);
37 t = strchr(mail, '<'); 37 t = strchr(mail, '<');
38 if (t) 38 if (t)
39 t++; 39 t++;
40 else 40 else
41 t = mail; 41 t = mail;
42 t2 = strchr(t, '>'); 42 t2 = strchr(t, '>');
43 if (t2) 43 if (t2)
44 *t2 = '\0'; 44 *t2 = '\0';
45 html("<email>"); 45 html("<email>");
46 html_txt(t); 46 html_txt(t);
47 html("</email>\n"); 47 html("</email>\n");
48 free(mail); 48 free(mail);
49 } 49 }
50 html("</author>\n"); 50 html("</author>\n");
51 html("<published>"); 51 html("<published>");
52 cgit_print_date(info->author_date, FMT_ATOMDATE, ctx.cfg.local_time); 52 cgit_print_date(info->author_date, FMT_ATOMDATE, ctx.cfg.local_time);
53 html("</published>\n"); 53 html("</published>\n");
54 if (host) { 54 if (host) {
55 html("<link rel='alternate' type='text/html' href='"); 55 html("<link rel='alternate' type='text/html' href='");
56 html(cgit_httpscheme()); 56 html(cgit_httpscheme());
57 html_attr(host); 57 html_attr(host);
58 html_attr(cgit_pageurl(ctx.repo->url, "commit", NULL)); 58 html_attr(cgit_pageurl(ctx.repo->url, "commit", NULL));
59 if (ctx.cfg.virtual_root) 59 if (ctx.cfg.virtual_root)
60 delim = '?'; 60 delim = '?';
61 htmlf("%cid=%s", delim, hex); 61 htmlf("%cid=%s", delim, hex);
62 html("'/>\n"); 62 html("'/>\n");
63 } 63 }
64 htmlf("<id>%s</id>\n", hex); 64 htmlf("<id>%s</id>\n", hex);
65 html("<content type='text'>\n"); 65 html("<content type='text'>\n");
66 html_txt(info->msg); 66 html_txt(info->msg);
67 html("</content>\n"); 67 html("</content>\n");
68 html("<content type='xhtml'>\n"); 68 html("<content type='xhtml'>\n");
69 html("<div xmlns='http://www.w3.org/1999/xhtml'>\n"); 69 html("<div xmlns='http://www.w3.org/1999/xhtml'>\n");
70 html("<pre>\n"); 70 html("<pre>\n");
71 html_txt(info->msg); 71 html_txt(info->msg);
72 html("</pre>\n"); 72 html("</pre>\n");
73 html("</div>\n"); 73 html("</div>\n");
74 html("</content>\n"); 74 html("</content>\n");
75 html("</entry>\n"); 75 html("</entry>\n");
76 cgit_free_commitinfo(info); 76 cgit_free_commitinfo(info);
77} 77}
78 78
79 79
80void cgit_print_atom(char *tip, char *path, int max_count) 80void cgit_print_atom(char *tip, char *path, int max_count)
81{ 81{
82 char *host; 82 char *host;
83 const char *argv[] = {NULL, tip, NULL, NULL, NULL}; 83 const char *argv[] = {NULL, tip, NULL, NULL, NULL};
84 struct commit *commit; 84 struct commit *commit;
85 struct rev_info rev; 85 struct rev_info rev;
86 int argc = 2; 86 int argc = 2;
87 87
88 if (!tip) 88 if (ctx.qry.show_all)
89 argv[1] = "--all";
90 else if (!tip)
89 argv[1] = ctx.qry.head; 91 argv[1] = ctx.qry.head;
90 92
91 if (path) { 93 if (path) {
92 argv[argc++] = "--"; 94 argv[argc++] = "--";
93 argv[argc++] = path; 95 argv[argc++] = path;
94 } 96 }
95 97
96 init_revisions(&rev, NULL); 98 init_revisions(&rev, NULL);
97 rev.abbrev = DEFAULT_ABBREV; 99 rev.abbrev = DEFAULT_ABBREV;
98 rev.commit_format = CMIT_FMT_DEFAULT; 100 rev.commit_format = CMIT_FMT_DEFAULT;
99 rev.verbose_header = 1; 101 rev.verbose_header = 1;
100 rev.show_root_diff = 0; 102 rev.show_root_diff = 0;
101 rev.max_count = max_count; 103 rev.max_count = max_count;
102 setup_revisions(argc, argv, &rev, NULL); 104 setup_revisions(argc, argv, &rev, NULL);
103 prepare_revision_walk(&rev); 105 prepare_revision_walk(&rev);
104 106
105 host = cgit_hosturl(); 107 host = cgit_hosturl();
106 ctx.page.mimetype = "text/xml"; 108 ctx.page.mimetype = "text/xml";
107 ctx.page.charset = "utf-8"; 109 ctx.page.charset = "utf-8";
108 cgit_print_http_headers(&ctx); 110 cgit_print_http_headers(&ctx);
109 html("<feed xmlns='http://www.w3.org/2005/Atom'>\n"); 111 html("<feed xmlns='http://www.w3.org/2005/Atom'>\n");
110 html("<title>"); 112 html("<title>");
111 html_txt(ctx.repo->name); 113 html_txt(ctx.repo->name);
112 html("</title>\n"); 114 html("</title>\n");
113 html("<subtitle>"); 115 html("<subtitle>");
114 html_txt(ctx.repo->desc); 116 html_txt(ctx.repo->desc);
115 html("</subtitle>\n"); 117 html("</subtitle>\n");
116 if (host) { 118 if (host) {
117 html("<link rel='alternate' type='text/html' href='"); 119 html("<link rel='alternate' type='text/html' href='");
118 html(cgit_httpscheme()); 120 html(cgit_httpscheme());
119 html_attr(host); 121 html_attr(host);
120 html_attr(cgit_repourl(ctx.repo->url)); 122 html_attr(cgit_repourl(ctx.repo->url));
121 html("'/>\n"); 123 html("'/>\n");
122 } 124 }
123 while ((commit = get_revision(&rev)) != NULL) { 125 while ((commit = get_revision(&rev)) != NULL) {
124 add_entry(commit, host); 126 add_entry(commit, host);
125 free(commit->buffer); 127 free(commit->buffer);
126 commit->buffer = NULL; 128 commit->buffer = NULL;
127 free_commit_list(commit->parents); 129 free_commit_list(commit->parents);
128 commit->parents = NULL; 130 commit->parents = NULL;
129 } 131 }
130 html("</feed>\n"); 132 html("</feed>\n");
131} 133}