summaryrefslogtreecommitdiffabout
path: root/cgit.c
authorLars Hjemli <hjemli@gmail.com>2008-07-27 10:32:08 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2008-07-27 10:32:08 (UTC)
commit25c84326deff579d5de4b880f9dca2690bdc8569 (patch) (unidiff)
tree9ca41073e0e06e6dc24f7800182bf4a7b22f548c /cgit.c
parent2d6ee032d0c2f84ebcfaa12d3289e85cfab18fcd (diff)
downloadcgit-25c84326deff579d5de4b880f9dca2690bdc8569.zip
cgit-25c84326deff579d5de4b880f9dca2690bdc8569.tar.gz
cgit-25c84326deff579d5de4b880f9dca2690bdc8569.tar.bz2
Be prepared for empty repositories
Before this patch, cgit would segfault on repositories with no refs. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'cgit.c') (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/cgit.c b/cgit.c
index 8795085..cefeddf 100644
--- a/cgit.c
+++ b/cgit.c
@@ -162,131 +162,135 @@ static void prepare_context(struct cgit_context *ctx)
162 ctx->cfg.cache_dynamic_ttl = 5; 162 ctx->cfg.cache_dynamic_ttl = 5;
163 ctx->cfg.cache_max_create_time = 5; 163 ctx->cfg.cache_max_create_time = 5;
164 ctx->cfg.cache_repo_ttl = 5; 164 ctx->cfg.cache_repo_ttl = 5;
165 ctx->cfg.cache_root = CGIT_CACHE_ROOT; 165 ctx->cfg.cache_root = CGIT_CACHE_ROOT;
166 ctx->cfg.cache_root_ttl = 5; 166 ctx->cfg.cache_root_ttl = 5;
167 ctx->cfg.cache_static_ttl = -1; 167 ctx->cfg.cache_static_ttl = -1;
168 ctx->cfg.css = "/cgit.css"; 168 ctx->cfg.css = "/cgit.css";
169 ctx->cfg.logo = "/git-logo.png"; 169 ctx->cfg.logo = "/git-logo.png";
170 ctx->cfg.max_repo_count = 50; 170 ctx->cfg.max_repo_count = 50;
171 ctx->cfg.max_commit_count = 50; 171 ctx->cfg.max_commit_count = 50;
172 ctx->cfg.max_lock_attempts = 5; 172 ctx->cfg.max_lock_attempts = 5;
173 ctx->cfg.max_msg_len = 60; 173 ctx->cfg.max_msg_len = 60;
174 ctx->cfg.max_repodesc_len = 60; 174 ctx->cfg.max_repodesc_len = 60;
175 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; 175 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";
176 ctx->cfg.renamelimit = -1; 176 ctx->cfg.renamelimit = -1;
177 ctx->cfg.robots = "index, nofollow"; 177 ctx->cfg.robots = "index, nofollow";
178 ctx->cfg.root_title = "Git repository browser"; 178 ctx->cfg.root_title = "Git repository browser";
179 ctx->cfg.root_desc = "a fast webinterface for the git dscm"; 179 ctx->cfg.root_desc = "a fast webinterface for the git dscm";
180 ctx->cfg.script_name = CGIT_SCRIPT_NAME; 180 ctx->cfg.script_name = CGIT_SCRIPT_NAME;
181 ctx->page.mimetype = "text/html"; 181 ctx->page.mimetype = "text/html";
182 ctx->page.charset = PAGE_ENCODING; 182 ctx->page.charset = PAGE_ENCODING;
183 ctx->page.filename = NULL; 183 ctx->page.filename = NULL;
184 ctx->page.modified = time(NULL); 184 ctx->page.modified = time(NULL);
185 ctx->page.expires = ctx->page.modified; 185 ctx->page.expires = ctx->page.modified;
186} 186}
187 187
188struct refmatch { 188struct refmatch {
189 char *req_ref; 189 char *req_ref;
190 char *first_ref; 190 char *first_ref;
191 int match; 191 int match;
192}; 192};
193 193
194int find_current_ref(const char *refname, const unsigned char *sha1, 194int find_current_ref(const char *refname, const unsigned char *sha1,
195 int flags, void *cb_data) 195 int flags, void *cb_data)
196{ 196{
197 struct refmatch *info; 197 struct refmatch *info;
198 198
199 info = (struct refmatch *)cb_data; 199 info = (struct refmatch *)cb_data;
200 if (!strcmp(refname, info->req_ref)) 200 if (!strcmp(refname, info->req_ref))
201 info->match = 1; 201 info->match = 1;
202 if (!info->first_ref) 202 if (!info->first_ref)
203 info->first_ref = xstrdup(refname); 203 info->first_ref = xstrdup(refname);
204 return info->match; 204 return info->match;
205} 205}
206 206
207char *find_default_branch(struct cgit_repo *repo) 207char *find_default_branch(struct cgit_repo *repo)
208{ 208{
209 struct refmatch info; 209 struct refmatch info;
210 char *ref;
210 211
211 info.req_ref = repo->defbranch; 212 info.req_ref = repo->defbranch;
212 info.first_ref = NULL; 213 info.first_ref = NULL;
213 info.match = 0; 214 info.match = 0;
214 for_each_branch_ref(find_current_ref, &info); 215 for_each_branch_ref(find_current_ref, &info);
215 if (info.match) 216 if (info.match)
216 return info.req_ref; 217 ref = info.req_ref;
217 else 218 else
218 return info.first_ref; 219 ref = info.first_ref;
220 if (ref)
221 ref = xstrdup(ref);
222 return ref;
219} 223}
220 224
221static int prepare_repo_cmd(struct cgit_context *ctx) 225static int prepare_repo_cmd(struct cgit_context *ctx)
222{ 226{
223 char *tmp; 227 char *tmp;
224 unsigned char sha1[20]; 228 unsigned char sha1[20];
225 int nongit = 0; 229 int nongit = 0;
226 230
227 setenv("GIT_DIR", ctx->repo->path, 1); 231 setenv("GIT_DIR", ctx->repo->path, 1);
228 setup_git_directory_gently(&nongit); 232 setup_git_directory_gently(&nongit);
229 if (nongit) { 233 if (nongit) {
230 ctx->page.title = fmt("%s - %s", ctx->cfg.root_title, 234 ctx->page.title = fmt("%s - %s", ctx->cfg.root_title,
231 "config error"); 235 "config error");
232 tmp = fmt("Not a git repository: '%s'", ctx->repo->path); 236 tmp = fmt("Not a git repository: '%s'", ctx->repo->path);
233 ctx->repo = NULL; 237 ctx->repo = NULL;
234 cgit_print_http_headers(ctx); 238 cgit_print_http_headers(ctx);
235 cgit_print_docstart(ctx); 239 cgit_print_docstart(ctx);
236 cgit_print_pageheader(ctx); 240 cgit_print_pageheader(ctx);
237 cgit_print_error(tmp); 241 cgit_print_error(tmp);
238 cgit_print_docend(); 242 cgit_print_docend();
239 return 1; 243 return 1;
240 } 244 }
241 ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc); 245 ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc);
242 246
243 if (!ctx->qry.head) { 247 if (!ctx->qry.head) {
244 ctx->qry.head = xstrdup(find_default_branch(ctx->repo)); 248 ctx->qry.head = find_default_branch(ctx->repo);
245 ctx->repo->defbranch = ctx->qry.head; 249 ctx->repo->defbranch = ctx->qry.head;
246 } 250 }
247 251
248 if (!ctx->qry.head) { 252 if (!ctx->qry.head) {
249 cgit_print_http_headers(ctx); 253 cgit_print_http_headers(ctx);
250 cgit_print_docstart(ctx); 254 cgit_print_docstart(ctx);
251 cgit_print_pageheader(ctx); 255 cgit_print_pageheader(ctx);
252 cgit_print_error("Repository seems to be empty"); 256 cgit_print_error("Repository seems to be empty");
253 cgit_print_docend(); 257 cgit_print_docend();
254 return 1; 258 return 1;
255 } 259 }
256 260
257 if (get_sha1(ctx->qry.head, sha1)) { 261 if (get_sha1(ctx->qry.head, sha1)) {
258 tmp = xstrdup(ctx->qry.head); 262 tmp = xstrdup(ctx->qry.head);
259 ctx->qry.head = ctx->repo->defbranch; 263 ctx->qry.head = ctx->repo->defbranch;
260 cgit_print_http_headers(ctx); 264 cgit_print_http_headers(ctx);
261 cgit_print_docstart(ctx); 265 cgit_print_docstart(ctx);
262 cgit_print_pageheader(ctx); 266 cgit_print_pageheader(ctx);
263 cgit_print_error(fmt("Invalid branch: %s", tmp)); 267 cgit_print_error(fmt("Invalid branch: %s", tmp));
264 cgit_print_docend(); 268 cgit_print_docend();
265 return 1; 269 return 1;
266 } 270 }
267 return 0; 271 return 0;
268} 272}
269 273
270static void process_request(void *cbdata) 274static void process_request(void *cbdata)
271{ 275{
272 struct cgit_context *ctx = cbdata; 276 struct cgit_context *ctx = cbdata;
273 struct cgit_cmd *cmd; 277 struct cgit_cmd *cmd;
274 278
275 cmd = cgit_get_cmd(ctx); 279 cmd = cgit_get_cmd(ctx);
276 if (!cmd) { 280 if (!cmd) {
277 ctx->page.title = "cgit error"; 281 ctx->page.title = "cgit error";
278 ctx->repo = NULL; 282 ctx->repo = NULL;
279 cgit_print_http_headers(ctx); 283 cgit_print_http_headers(ctx);
280 cgit_print_docstart(ctx); 284 cgit_print_docstart(ctx);
281 cgit_print_pageheader(ctx); 285 cgit_print_pageheader(ctx);
282 cgit_print_error("Invalid request"); 286 cgit_print_error("Invalid request");
283 cgit_print_docend(); 287 cgit_print_docend();
284 return; 288 return;
285 } 289 }
286 290
287 if (cmd->want_repo && !ctx->repo) { 291 if (cmd->want_repo && !ctx->repo) {
288 cgit_print_http_headers(ctx); 292 cgit_print_http_headers(ctx);
289 cgit_print_docstart(ctx); 293 cgit_print_docstart(ctx);
290 cgit_print_pageheader(ctx); 294 cgit_print_pageheader(ctx);
291 cgit_print_error(fmt("No repository selected")); 295 cgit_print_error(fmt("No repository selected"));
292 cgit_print_docend(); 296 cgit_print_docend();