summaryrefslogtreecommitdiffabout
path: root/cgit.c
authorLars Hjemli <hjemli@gmail.com>2008-12-06 16:38:19 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2008-12-06 16:38:19 (UTC)
commitf86a23ff537258d36bf8f1876fa7a4bede6673d8 (patch) (unidiff)
tree8328d415416058cdc5b0fd2c6564ddcab5766c7a /cgit.c
parent140012d7a8e51df5a9f9c556696778b86ade4fc9 (diff)
downloadcgit-f86a23ff537258d36bf8f1876fa7a4bede6673d8.zip
cgit-f86a23ff537258d36bf8f1876fa7a4bede6673d8.tar.gz
cgit-f86a23ff537258d36bf8f1876fa7a4bede6673d8.tar.bz2
Add a 'stats' page to each repo
This new page, which is disabled by default, can be used to print some statistics about the number of commits per period in the repository, where period can be either weeks, months, quarters or years. The function can be activated globally by setting 'enable-stats=1' in cgitrc and disabled for individual repos by setting 'repo.enable-stats=0'. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'cgit.c') (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/cgit.c b/cgit.c
index c82587b..22b6d7c 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,348 +1,354 @@
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 "scan-tree.h" 15#include "scan-tree.h"
16 16
17const char *cgit_version = CGIT_VERSION; 17const char *cgit_version = CGIT_VERSION;
18 18
19void config_cb(const char *name, const char *value) 19void config_cb(const char *name, const char *value)
20{ 20{
21 if (!strcmp(name, "root-title")) 21 if (!strcmp(name, "root-title"))
22 ctx.cfg.root_title = xstrdup(value); 22 ctx.cfg.root_title = xstrdup(value);
23 else if (!strcmp(name, "root-desc")) 23 else if (!strcmp(name, "root-desc"))
24 ctx.cfg.root_desc = xstrdup(value); 24 ctx.cfg.root_desc = xstrdup(value);
25 else if (!strcmp(name, "root-readme")) 25 else if (!strcmp(name, "root-readme"))
26 ctx.cfg.root_readme = xstrdup(value); 26 ctx.cfg.root_readme = xstrdup(value);
27 else if (!strcmp(name, "css")) 27 else if (!strcmp(name, "css"))
28 ctx.cfg.css = xstrdup(value); 28 ctx.cfg.css = xstrdup(value);
29 else if (!strcmp(name, "favicon")) 29 else if (!strcmp(name, "favicon"))
30 ctx.cfg.favicon = xstrdup(value); 30 ctx.cfg.favicon = xstrdup(value);
31 else if (!strcmp(name, "footer")) 31 else if (!strcmp(name, "footer"))
32 ctx.cfg.footer = xstrdup(value); 32 ctx.cfg.footer = xstrdup(value);
33 else if (!strcmp(name, "logo")) 33 else if (!strcmp(name, "logo"))
34 ctx.cfg.logo = xstrdup(value); 34 ctx.cfg.logo = xstrdup(value);
35 else if (!strcmp(name, "index-header")) 35 else if (!strcmp(name, "index-header"))
36 ctx.cfg.index_header = xstrdup(value); 36 ctx.cfg.index_header = xstrdup(value);
37 else if (!strcmp(name, "index-info")) 37 else if (!strcmp(name, "index-info"))
38 ctx.cfg.index_info = xstrdup(value); 38 ctx.cfg.index_info = xstrdup(value);
39 else if (!strcmp(name, "logo-link")) 39 else if (!strcmp(name, "logo-link"))
40 ctx.cfg.logo_link = xstrdup(value); 40 ctx.cfg.logo_link = xstrdup(value);
41 else if (!strcmp(name, "module-link")) 41 else if (!strcmp(name, "module-link"))
42 ctx.cfg.module_link = xstrdup(value); 42 ctx.cfg.module_link = xstrdup(value);
43 else if (!strcmp(name, "virtual-root")) { 43 else if (!strcmp(name, "virtual-root")) {
44 ctx.cfg.virtual_root = trim_end(value, '/'); 44 ctx.cfg.virtual_root = trim_end(value, '/');
45 if (!ctx.cfg.virtual_root && (!strcmp(value, "/"))) 45 if (!ctx.cfg.virtual_root && (!strcmp(value, "/")))
46 ctx.cfg.virtual_root = ""; 46 ctx.cfg.virtual_root = "";
47 } else if (!strcmp(name, "nocache")) 47 } else if (!strcmp(name, "nocache"))
48 ctx.cfg.nocache = atoi(value); 48 ctx.cfg.nocache = atoi(value);
49 else if (!strcmp(name, "snapshots")) 49 else if (!strcmp(name, "snapshots"))
50 ctx.cfg.snapshots = cgit_parse_snapshots_mask(value); 50 ctx.cfg.snapshots = cgit_parse_snapshots_mask(value);
51 else if (!strcmp(name, "enable-index-links")) 51 else if (!strcmp(name, "enable-index-links"))
52 ctx.cfg.enable_index_links = atoi(value); 52 ctx.cfg.enable_index_links = atoi(value);
53 else if (!strcmp(name, "enable-log-filecount")) 53 else if (!strcmp(name, "enable-log-filecount"))
54 ctx.cfg.enable_log_filecount = atoi(value); 54 ctx.cfg.enable_log_filecount = atoi(value);
55 else if (!strcmp(name, "enable-log-linecount")) 55 else if (!strcmp(name, "enable-log-linecount"))
56 ctx.cfg.enable_log_linecount = atoi(value); 56 ctx.cfg.enable_log_linecount = atoi(value);
57 else if (!strcmp(name, "enable-stats"))
58 ctx.cfg.enable_stats = atoi(value);
57 else if (!strcmp(name, "cache-size")) 59 else if (!strcmp(name, "cache-size"))
58 ctx.cfg.cache_size = atoi(value); 60 ctx.cfg.cache_size = atoi(value);
59 else if (!strcmp(name, "cache-root")) 61 else if (!strcmp(name, "cache-root"))
60 ctx.cfg.cache_root = xstrdup(value); 62 ctx.cfg.cache_root = xstrdup(value);
61 else if (!strcmp(name, "cache-root-ttl")) 63 else if (!strcmp(name, "cache-root-ttl"))
62 ctx.cfg.cache_root_ttl = atoi(value); 64 ctx.cfg.cache_root_ttl = atoi(value);
63 else if (!strcmp(name, "cache-repo-ttl")) 65 else if (!strcmp(name, "cache-repo-ttl"))
64 ctx.cfg.cache_repo_ttl = atoi(value); 66 ctx.cfg.cache_repo_ttl = atoi(value);
65 else if (!strcmp(name, "cache-static-ttl")) 67 else if (!strcmp(name, "cache-static-ttl"))
66 ctx.cfg.cache_static_ttl = atoi(value); 68 ctx.cfg.cache_static_ttl = atoi(value);
67 else if (!strcmp(name, "cache-dynamic-ttl")) 69 else if (!strcmp(name, "cache-dynamic-ttl"))
68 ctx.cfg.cache_dynamic_ttl = atoi(value); 70 ctx.cfg.cache_dynamic_ttl = atoi(value);
69 else if (!strcmp(name, "max-message-length")) 71 else if (!strcmp(name, "max-message-length"))
70 ctx.cfg.max_msg_len = atoi(value); 72 ctx.cfg.max_msg_len = atoi(value);
71 else if (!strcmp(name, "max-repodesc-length")) 73 else if (!strcmp(name, "max-repodesc-length"))
72 ctx.cfg.max_repodesc_len = atoi(value); 74 ctx.cfg.max_repodesc_len = atoi(value);
73 else if (!strcmp(name, "max-repo-count")) 75 else if (!strcmp(name, "max-repo-count"))
74 ctx.cfg.max_repo_count = atoi(value); 76 ctx.cfg.max_repo_count = atoi(value);
75 else if (!strcmp(name, "max-commit-count")) 77 else if (!strcmp(name, "max-commit-count"))
76 ctx.cfg.max_commit_count = atoi(value); 78 ctx.cfg.max_commit_count = atoi(value);
77 else if (!strcmp(name, "summary-log")) 79 else if (!strcmp(name, "summary-log"))
78 ctx.cfg.summary_log = atoi(value); 80 ctx.cfg.summary_log = atoi(value);
79 else if (!strcmp(name, "summary-branches")) 81 else if (!strcmp(name, "summary-branches"))
80 ctx.cfg.summary_branches = atoi(value); 82 ctx.cfg.summary_branches = atoi(value);
81 else if (!strcmp(name, "summary-tags")) 83 else if (!strcmp(name, "summary-tags"))
82 ctx.cfg.summary_tags = atoi(value); 84 ctx.cfg.summary_tags = atoi(value);
83 else if (!strcmp(name, "agefile")) 85 else if (!strcmp(name, "agefile"))
84 ctx.cfg.agefile = xstrdup(value); 86 ctx.cfg.agefile = xstrdup(value);
85 else if (!strcmp(name, "renamelimit")) 87 else if (!strcmp(name, "renamelimit"))
86 ctx.cfg.renamelimit = atoi(value); 88 ctx.cfg.renamelimit = atoi(value);
87 else if (!strcmp(name, "robots")) 89 else if (!strcmp(name, "robots"))
88 ctx.cfg.robots = xstrdup(value); 90 ctx.cfg.robots = xstrdup(value);
89 else if (!strcmp(name, "clone-prefix")) 91 else if (!strcmp(name, "clone-prefix"))
90 ctx.cfg.clone_prefix = xstrdup(value); 92 ctx.cfg.clone_prefix = xstrdup(value);
91 else if (!strcmp(name, "local-time")) 93 else if (!strcmp(name, "local-time"))
92 ctx.cfg.local_time = atoi(value); 94 ctx.cfg.local_time = atoi(value);
93 else if (!strcmp(name, "repo.group")) 95 else if (!strcmp(name, "repo.group"))
94 ctx.cfg.repo_group = xstrdup(value); 96 ctx.cfg.repo_group = xstrdup(value);
95 else if (!strcmp(name, "repo.url")) 97 else if (!strcmp(name, "repo.url"))
96 ctx.repo = cgit_add_repo(value); 98 ctx.repo = cgit_add_repo(value);
97 else if (!strcmp(name, "repo.name")) 99 else if (!strcmp(name, "repo.name"))
98 ctx.repo->name = xstrdup(value); 100 ctx.repo->name = xstrdup(value);
99 else if (ctx.repo && !strcmp(name, "repo.path")) 101 else if (ctx.repo && !strcmp(name, "repo.path"))
100 ctx.repo->path = trim_end(value, '/'); 102 ctx.repo->path = trim_end(value, '/');
101 else if (ctx.repo && !strcmp(name, "repo.clone-url")) 103 else if (ctx.repo && !strcmp(name, "repo.clone-url"))
102 ctx.repo->clone_url = xstrdup(value); 104 ctx.repo->clone_url = xstrdup(value);
103 else if (ctx.repo && !strcmp(name, "repo.desc")) 105 else if (ctx.repo && !strcmp(name, "repo.desc"))
104 ctx.repo->desc = xstrdup(value); 106 ctx.repo->desc = xstrdup(value);
105 else if (ctx.repo && !strcmp(name, "repo.owner")) 107 else if (ctx.repo && !strcmp(name, "repo.owner"))
106 ctx.repo->owner = xstrdup(value); 108 ctx.repo->owner = xstrdup(value);
107 else if (ctx.repo && !strcmp(name, "repo.defbranch")) 109 else if (ctx.repo && !strcmp(name, "repo.defbranch"))
108 ctx.repo->defbranch = xstrdup(value); 110 ctx.repo->defbranch = xstrdup(value);
109 else if (ctx.repo && !strcmp(name, "repo.snapshots")) 111 else if (ctx.repo && !strcmp(name, "repo.snapshots"))
110 ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */ 112 ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */
111 else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount")) 113 else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount"))
112 ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); 114 ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value);
113 else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount")) 115 else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount"))
114 ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); 116 ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value);
117 else if (ctx.repo && !strcmp(name, "repo.enable-stats"))
118 ctx.repo->enable_stats = ctx.cfg.enable_stats && atoi(value);
115 else if (ctx.repo && !strcmp(name, "repo.module-link")) 119 else if (ctx.repo && !strcmp(name, "repo.module-link"))
116 ctx.repo->module_link= xstrdup(value); 120 ctx.repo->module_link= xstrdup(value);
117 else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) { 121 else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) {
118 if (*value == '/') 122 if (*value == '/')
119 ctx.repo->readme = xstrdup(value); 123 ctx.repo->readme = xstrdup(value);
120 else 124 else
121 ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, value)); 125 ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, value));
122 } else if (!strcmp(name, "include")) 126 } else if (!strcmp(name, "include"))
123 parse_configfile(value, config_cb); 127 parse_configfile(value, config_cb);
124} 128}
125 129
126static void querystring_cb(const char *name, const char *value) 130static void querystring_cb(const char *name, const char *value)
127{ 131{
128 if (!strcmp(name,"r")) { 132 if (!strcmp(name,"r")) {
129 ctx.qry.repo = xstrdup(value); 133 ctx.qry.repo = xstrdup(value);
130 ctx.repo = cgit_get_repoinfo(value); 134 ctx.repo = cgit_get_repoinfo(value);
131 } else if (!strcmp(name, "p")) { 135 } else if (!strcmp(name, "p")) {
132 ctx.qry.page = xstrdup(value); 136 ctx.qry.page = xstrdup(value);
133 } else if (!strcmp(name, "url")) { 137 } else if (!strcmp(name, "url")) {
134 ctx.qry.url = xstrdup(value); 138 ctx.qry.url = xstrdup(value);
135 cgit_parse_url(value); 139 cgit_parse_url(value);
136 } else if (!strcmp(name, "qt")) { 140 } else if (!strcmp(name, "qt")) {
137 ctx.qry.grep = xstrdup(value); 141 ctx.qry.grep = xstrdup(value);
138 } else if (!strcmp(name, "q")) { 142 } else if (!strcmp(name, "q")) {
139 ctx.qry.search = xstrdup(value); 143 ctx.qry.search = xstrdup(value);
140 } else if (!strcmp(name, "h")) { 144 } else if (!strcmp(name, "h")) {
141 ctx.qry.head = xstrdup(value); 145 ctx.qry.head = xstrdup(value);
142 ctx.qry.has_symref = 1; 146 ctx.qry.has_symref = 1;
143 } else if (!strcmp(name, "id")) { 147 } else if (!strcmp(name, "id")) {
144 ctx.qry.sha1 = xstrdup(value); 148 ctx.qry.sha1 = xstrdup(value);
145 ctx.qry.has_sha1 = 1; 149 ctx.qry.has_sha1 = 1;
146 } else if (!strcmp(name, "id2")) { 150 } else if (!strcmp(name, "id2")) {
147 ctx.qry.sha2 = xstrdup(value); 151 ctx.qry.sha2 = xstrdup(value);
148 ctx.qry.has_sha1 = 1; 152 ctx.qry.has_sha1 = 1;
149 } else if (!strcmp(name, "ofs")) { 153 } else if (!strcmp(name, "ofs")) {
150 ctx.qry.ofs = atoi(value); 154 ctx.qry.ofs = atoi(value);
151 } else if (!strcmp(name, "path")) { 155 } else if (!strcmp(name, "path")) {
152 ctx.qry.path = trim_end(value, '/'); 156 ctx.qry.path = trim_end(value, '/');
153 } else if (!strcmp(name, "name")) { 157 } else if (!strcmp(name, "name")) {
154 ctx.qry.name = xstrdup(value); 158 ctx.qry.name = xstrdup(value);
155 } else if (!strcmp(name, "mimetype")) { 159 } else if (!strcmp(name, "mimetype")) {
156 ctx.qry.mimetype = xstrdup(value); 160 ctx.qry.mimetype = xstrdup(value);
161 } else if (!strcmp(name, "period")) {
162 ctx.qry.period = xstrdup(value);
157 } 163 }
158} 164}
159 165
160static void prepare_context(struct cgit_context *ctx) 166static void prepare_context(struct cgit_context *ctx)
161{ 167{
162 memset(ctx, 0, sizeof(ctx)); 168 memset(ctx, 0, sizeof(ctx));
163 ctx->cfg.agefile = "info/web/last-modified"; 169 ctx->cfg.agefile = "info/web/last-modified";
164 ctx->cfg.nocache = 0; 170 ctx->cfg.nocache = 0;
165 ctx->cfg.cache_size = 0; 171 ctx->cfg.cache_size = 0;
166 ctx->cfg.cache_dynamic_ttl = 5; 172 ctx->cfg.cache_dynamic_ttl = 5;
167 ctx->cfg.cache_max_create_time = 5; 173 ctx->cfg.cache_max_create_time = 5;
168 ctx->cfg.cache_repo_ttl = 5; 174 ctx->cfg.cache_repo_ttl = 5;
169 ctx->cfg.cache_root = CGIT_CACHE_ROOT; 175 ctx->cfg.cache_root = CGIT_CACHE_ROOT;
170 ctx->cfg.cache_root_ttl = 5; 176 ctx->cfg.cache_root_ttl = 5;
171 ctx->cfg.cache_static_ttl = -1; 177 ctx->cfg.cache_static_ttl = -1;
172 ctx->cfg.css = "/cgit.css"; 178 ctx->cfg.css = "/cgit.css";
173 ctx->cfg.logo = "/git-logo.png"; 179 ctx->cfg.logo = "/git-logo.png";
174 ctx->cfg.local_time = 0; 180 ctx->cfg.local_time = 0;
175 ctx->cfg.max_repo_count = 50; 181 ctx->cfg.max_repo_count = 50;
176 ctx->cfg.max_commit_count = 50; 182 ctx->cfg.max_commit_count = 50;
177 ctx->cfg.max_lock_attempts = 5; 183 ctx->cfg.max_lock_attempts = 5;
178 ctx->cfg.max_msg_len = 80; 184 ctx->cfg.max_msg_len = 80;
179 ctx->cfg.max_repodesc_len = 80; 185 ctx->cfg.max_repodesc_len = 80;
180 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; 186 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";
181 ctx->cfg.renamelimit = -1; 187 ctx->cfg.renamelimit = -1;
182 ctx->cfg.robots = "index, nofollow"; 188 ctx->cfg.robots = "index, nofollow";
183 ctx->cfg.root_title = "Git repository browser"; 189 ctx->cfg.root_title = "Git repository browser";
184 ctx->cfg.root_desc = "a fast webinterface for the git dscm"; 190 ctx->cfg.root_desc = "a fast webinterface for the git dscm";
185 ctx->cfg.script_name = CGIT_SCRIPT_NAME; 191 ctx->cfg.script_name = CGIT_SCRIPT_NAME;
186 ctx->cfg.summary_branches = 10; 192 ctx->cfg.summary_branches = 10;
187 ctx->cfg.summary_log = 10; 193 ctx->cfg.summary_log = 10;
188 ctx->cfg.summary_tags = 10; 194 ctx->cfg.summary_tags = 10;
189 ctx->page.mimetype = "text/html"; 195 ctx->page.mimetype = "text/html";
190 ctx->page.charset = PAGE_ENCODING; 196 ctx->page.charset = PAGE_ENCODING;
191 ctx->page.filename = NULL; 197 ctx->page.filename = NULL;
192 ctx->page.size = 0; 198 ctx->page.size = 0;
193 ctx->page.modified = time(NULL); 199 ctx->page.modified = time(NULL);
194 ctx->page.expires = ctx->page.modified; 200 ctx->page.expires = ctx->page.modified;
195} 201}
196 202
197struct refmatch { 203struct refmatch {
198 char *req_ref; 204 char *req_ref;
199 char *first_ref; 205 char *first_ref;
200 int match; 206 int match;
201}; 207};
202 208
203int find_current_ref(const char *refname, const unsigned char *sha1, 209int find_current_ref(const char *refname, const unsigned char *sha1,
204 int flags, void *cb_data) 210 int flags, void *cb_data)
205{ 211{
206 struct refmatch *info; 212 struct refmatch *info;
207 213
208 info = (struct refmatch *)cb_data; 214 info = (struct refmatch *)cb_data;
209 if (!strcmp(refname, info->req_ref)) 215 if (!strcmp(refname, info->req_ref))
210 info->match = 1; 216 info->match = 1;
211 if (!info->first_ref) 217 if (!info->first_ref)
212 info->first_ref = xstrdup(refname); 218 info->first_ref = xstrdup(refname);
213 return info->match; 219 return info->match;
214} 220}
215 221
216char *find_default_branch(struct cgit_repo *repo) 222char *find_default_branch(struct cgit_repo *repo)
217{ 223{
218 struct refmatch info; 224 struct refmatch info;
219 char *ref; 225 char *ref;
220 226
221 info.req_ref = repo->defbranch; 227 info.req_ref = repo->defbranch;
222 info.first_ref = NULL; 228 info.first_ref = NULL;
223 info.match = 0; 229 info.match = 0;
224 for_each_branch_ref(find_current_ref, &info); 230 for_each_branch_ref(find_current_ref, &info);
225 if (info.match) 231 if (info.match)
226 ref = info.req_ref; 232 ref = info.req_ref;
227 else 233 else
228 ref = info.first_ref; 234 ref = info.first_ref;
229 if (ref) 235 if (ref)
230 ref = xstrdup(ref); 236 ref = xstrdup(ref);
231 return ref; 237 return ref;
232} 238}
233 239
234static int prepare_repo_cmd(struct cgit_context *ctx) 240static int prepare_repo_cmd(struct cgit_context *ctx)
235{ 241{
236 char *tmp; 242 char *tmp;
237 unsigned char sha1[20]; 243 unsigned char sha1[20];
238 int nongit = 0; 244 int nongit = 0;
239 245
240 setenv("GIT_DIR", ctx->repo->path, 1); 246 setenv("GIT_DIR", ctx->repo->path, 1);
241 setup_git_directory_gently(&nongit); 247 setup_git_directory_gently(&nongit);
242 if (nongit) { 248 if (nongit) {
243 ctx->page.title = fmt("%s - %s", ctx->cfg.root_title, 249 ctx->page.title = fmt("%s - %s", ctx->cfg.root_title,
244 "config error"); 250 "config error");
245 tmp = fmt("Not a git repository: '%s'", ctx->repo->path); 251 tmp = fmt("Not a git repository: '%s'", ctx->repo->path);
246 ctx->repo = NULL; 252 ctx->repo = NULL;
247 cgit_print_http_headers(ctx); 253 cgit_print_http_headers(ctx);
248 cgit_print_docstart(ctx); 254 cgit_print_docstart(ctx);
249 cgit_print_pageheader(ctx); 255 cgit_print_pageheader(ctx);
250 cgit_print_error(tmp); 256 cgit_print_error(tmp);
251 cgit_print_docend(); 257 cgit_print_docend();
252 return 1; 258 return 1;
253 } 259 }
254 ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc); 260 ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc);
255 261
256 if (!ctx->qry.head) { 262 if (!ctx->qry.head) {
257 ctx->qry.nohead = 1; 263 ctx->qry.nohead = 1;
258 ctx->qry.head = find_default_branch(ctx->repo); 264 ctx->qry.head = find_default_branch(ctx->repo);
259 ctx->repo->defbranch = ctx->qry.head; 265 ctx->repo->defbranch = ctx->qry.head;
260 } 266 }
261 267
262 if (!ctx->qry.head) { 268 if (!ctx->qry.head) {
263 cgit_print_http_headers(ctx); 269 cgit_print_http_headers(ctx);
264 cgit_print_docstart(ctx); 270 cgit_print_docstart(ctx);
265 cgit_print_pageheader(ctx); 271 cgit_print_pageheader(ctx);
266 cgit_print_error("Repository seems to be empty"); 272 cgit_print_error("Repository seems to be empty");
267 cgit_print_docend(); 273 cgit_print_docend();
268 return 1; 274 return 1;
269 } 275 }
270 276
271 if (get_sha1(ctx->qry.head, sha1)) { 277 if (get_sha1(ctx->qry.head, sha1)) {
272 tmp = xstrdup(ctx->qry.head); 278 tmp = xstrdup(ctx->qry.head);
273 ctx->qry.head = ctx->repo->defbranch; 279 ctx->qry.head = ctx->repo->defbranch;
274 cgit_print_http_headers(ctx); 280 cgit_print_http_headers(ctx);
275 cgit_print_docstart(ctx); 281 cgit_print_docstart(ctx);
276 cgit_print_pageheader(ctx); 282 cgit_print_pageheader(ctx);
277 cgit_print_error(fmt("Invalid branch: %s", tmp)); 283 cgit_print_error(fmt("Invalid branch: %s", tmp));
278 cgit_print_docend(); 284 cgit_print_docend();
279 return 1; 285 return 1;
280 } 286 }
281 return 0; 287 return 0;
282} 288}
283 289
284static void process_request(void *cbdata) 290static void process_request(void *cbdata)
285{ 291{
286 struct cgit_context *ctx = cbdata; 292 struct cgit_context *ctx = cbdata;
287 struct cgit_cmd *cmd; 293 struct cgit_cmd *cmd;
288 294
289 cmd = cgit_get_cmd(ctx); 295 cmd = cgit_get_cmd(ctx);
290 if (!cmd) { 296 if (!cmd) {
291 ctx->page.title = "cgit error"; 297 ctx->page.title = "cgit error";
292 ctx->repo = NULL; 298 ctx->repo = NULL;
293 cgit_print_http_headers(ctx); 299 cgit_print_http_headers(ctx);
294 cgit_print_docstart(ctx); 300 cgit_print_docstart(ctx);
295 cgit_print_pageheader(ctx); 301 cgit_print_pageheader(ctx);
296 cgit_print_error("Invalid request"); 302 cgit_print_error("Invalid request");
297 cgit_print_docend(); 303 cgit_print_docend();
298 return; 304 return;
299 } 305 }
300 306
301 if (cmd->want_repo && !ctx->repo) { 307 if (cmd->want_repo && !ctx->repo) {
302 cgit_print_http_headers(ctx); 308 cgit_print_http_headers(ctx);
303 cgit_print_docstart(ctx); 309 cgit_print_docstart(ctx);
304 cgit_print_pageheader(ctx); 310 cgit_print_pageheader(ctx);
305 cgit_print_error(fmt("No repository selected")); 311 cgit_print_error(fmt("No repository selected"));
306 cgit_print_docend(); 312 cgit_print_docend();
307 return; 313 return;
308 } 314 }
309 315
310 if (ctx->repo && prepare_repo_cmd(ctx)) 316 if (ctx->repo && prepare_repo_cmd(ctx))
311 return; 317 return;
312 318
313 if (cmd->want_layout) { 319 if (cmd->want_layout) {
314 cgit_print_http_headers(ctx); 320 cgit_print_http_headers(ctx);
315 cgit_print_docstart(ctx); 321 cgit_print_docstart(ctx);
316 cgit_print_pageheader(ctx); 322 cgit_print_pageheader(ctx);
317 } 323 }
318 324
319 cmd->fn(ctx); 325 cmd->fn(ctx);
320 326
321 if (cmd->want_layout) 327 if (cmd->want_layout)
322 cgit_print_docend(); 328 cgit_print_docend();
323} 329}
324 330
325int cmp_repos(const void *a, const void *b) 331int cmp_repos(const void *a, const void *b)
326{ 332{
327 const struct cgit_repo *ra = a, *rb = b; 333 const struct cgit_repo *ra = a, *rb = b;
328 return strcmp(ra->url, rb->url); 334 return strcmp(ra->url, rb->url);
329} 335}
330 336
331void print_repo(struct cgit_repo *repo) 337void print_repo(struct cgit_repo *repo)
332{ 338{
333 printf("repo.url=%s\n", repo->url); 339 printf("repo.url=%s\n", repo->url);
334 printf("repo.name=%s\n", repo->name); 340 printf("repo.name=%s\n", repo->name);
335 printf("repo.path=%s\n", repo->path); 341 printf("repo.path=%s\n", repo->path);
336 if (repo->owner) 342 if (repo->owner)
337 printf("repo.owner=%s\n", repo->owner); 343 printf("repo.owner=%s\n", repo->owner);
338 if (repo->desc) 344 if (repo->desc)
339 printf("repo.desc=%s\n", repo->desc); 345 printf("repo.desc=%s\n", repo->desc);
340 if (repo->readme) 346 if (repo->readme)
341 printf("repo.readme=%s\n", repo->readme); 347 printf("repo.readme=%s\n", repo->readme);
342 printf("\n"); 348 printf("\n");
343} 349}
344 350
345void print_repolist(struct cgit_repolist *list) 351void print_repolist(struct cgit_repolist *list)
346{ 352{
347 int i; 353 int i;
348 354