summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/cgit.c b/cgit.c
index e498030..5259f56 100644
--- a/cgit.c
+++ b/cgit.c
@@ -310,199 +310,203 @@ static void prepare_context(struct cgit_context *ctx)
310 ctx->cfg.cache_static_ttl = -1; 310 ctx->cfg.cache_static_ttl = -1;
311 ctx->cfg.css = "/cgit.css"; 311 ctx->cfg.css = "/cgit.css";
312 ctx->cfg.logo = "/cgit.png"; 312 ctx->cfg.logo = "/cgit.png";
313 ctx->cfg.local_time = 0; 313 ctx->cfg.local_time = 0;
314 ctx->cfg.enable_gitweb_owner = 1; 314 ctx->cfg.enable_gitweb_owner = 1;
315 ctx->cfg.enable_tree_linenumbers = 1; 315 ctx->cfg.enable_tree_linenumbers = 1;
316 ctx->cfg.max_repo_count = 50; 316 ctx->cfg.max_repo_count = 50;
317 ctx->cfg.max_commit_count = 50; 317 ctx->cfg.max_commit_count = 50;
318 ctx->cfg.max_lock_attempts = 5; 318 ctx->cfg.max_lock_attempts = 5;
319 ctx->cfg.max_msg_len = 80; 319 ctx->cfg.max_msg_len = 80;
320 ctx->cfg.max_repodesc_len = 80; 320 ctx->cfg.max_repodesc_len = 80;
321 ctx->cfg.max_blob_size = 0; 321 ctx->cfg.max_blob_size = 0;
322 ctx->cfg.max_stats = 0; 322 ctx->cfg.max_stats = 0;
323 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; 323 ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";
324 ctx->cfg.project_list = NULL; 324 ctx->cfg.project_list = NULL;
325 ctx->cfg.renamelimit = -1; 325 ctx->cfg.renamelimit = -1;
326 ctx->cfg.remove_suffix = 0; 326 ctx->cfg.remove_suffix = 0;
327 ctx->cfg.robots = "index, nofollow"; 327 ctx->cfg.robots = "index, nofollow";
328 ctx->cfg.root_title = "Git repository browser"; 328 ctx->cfg.root_title = "Git repository browser";
329 ctx->cfg.root_desc = "a fast webinterface for the git dscm"; 329 ctx->cfg.root_desc = "a fast webinterface for the git dscm";
330 ctx->cfg.scan_hidden_path = 0; 330 ctx->cfg.scan_hidden_path = 0;
331 ctx->cfg.script_name = CGIT_SCRIPT_NAME; 331 ctx->cfg.script_name = CGIT_SCRIPT_NAME;
332 ctx->cfg.section = ""; 332 ctx->cfg.section = "";
333 ctx->cfg.summary_branches = 10; 333 ctx->cfg.summary_branches = 10;
334 ctx->cfg.summary_log = 10; 334 ctx->cfg.summary_log = 10;
335 ctx->cfg.summary_tags = 10; 335 ctx->cfg.summary_tags = 10;
336 ctx->cfg.max_atom_items = 10; 336 ctx->cfg.max_atom_items = 10;
337 ctx->cfg.ssdiff = 0; 337 ctx->cfg.ssdiff = 0;
338 ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG")); 338 ctx->env.cgit_config = xstrdupn(getenv("CGIT_CONFIG"));
339 ctx->env.http_host = xstrdupn(getenv("HTTP_HOST")); 339 ctx->env.http_host = xstrdupn(getenv("HTTP_HOST"));
340 ctx->env.https = xstrdupn(getenv("HTTPS")); 340 ctx->env.https = xstrdupn(getenv("HTTPS"));
341 ctx->env.no_http = xstrdupn(getenv("NO_HTTP")); 341 ctx->env.no_http = xstrdupn(getenv("NO_HTTP"));
342 ctx->env.path_info = xstrdupn(getenv("PATH_INFO")); 342 ctx->env.path_info = xstrdupn(getenv("PATH_INFO"));
343 ctx->env.query_string = xstrdupn(getenv("QUERY_STRING")); 343 ctx->env.query_string = xstrdupn(getenv("QUERY_STRING"));
344 ctx->env.request_method = xstrdupn(getenv("REQUEST_METHOD")); 344 ctx->env.request_method = xstrdupn(getenv("REQUEST_METHOD"));
345 ctx->env.script_name = xstrdupn(getenv("SCRIPT_NAME")); 345 ctx->env.script_name = xstrdupn(getenv("SCRIPT_NAME"));
346 ctx->env.server_name = xstrdupn(getenv("SERVER_NAME")); 346 ctx->env.server_name = xstrdupn(getenv("SERVER_NAME"));
347 ctx->env.server_port = xstrdupn(getenv("SERVER_PORT")); 347 ctx->env.server_port = xstrdupn(getenv("SERVER_PORT"));
348 ctx->page.mimetype = "text/html"; 348 ctx->page.mimetype = "text/html";
349 ctx->page.charset = PAGE_ENCODING; 349 ctx->page.charset = PAGE_ENCODING;
350 ctx->page.filename = NULL; 350 ctx->page.filename = NULL;
351 ctx->page.size = 0; 351 ctx->page.size = 0;
352 ctx->page.modified = time(NULL); 352 ctx->page.modified = time(NULL);
353 ctx->page.expires = ctx->page.modified; 353 ctx->page.expires = ctx->page.modified;
354 ctx->page.etag = NULL; 354 ctx->page.etag = NULL;
355 memset(&ctx->cfg.mimetypes, 0, sizeof(struct string_list)); 355 memset(&ctx->cfg.mimetypes, 0, sizeof(struct string_list));
356 if (ctx->env.script_name) 356 if (ctx->env.script_name)
357 ctx->cfg.script_name = ctx->env.script_name; 357 ctx->cfg.script_name = ctx->env.script_name;
358 if (ctx->env.query_string) 358 if (ctx->env.query_string)
359 ctx->qry.raw = ctx->env.query_string; 359 ctx->qry.raw = ctx->env.query_string;
360 if (!ctx->env.cgit_config) 360 if (!ctx->env.cgit_config)
361 ctx->env.cgit_config = CGIT_CONFIG; 361 ctx->env.cgit_config = CGIT_CONFIG;
362} 362}
363 363
364struct refmatch { 364struct refmatch {
365 char *req_ref; 365 char *req_ref;
366 char *first_ref; 366 char *first_ref;
367 int match; 367 int match;
368}; 368};
369 369
370int find_current_ref(const char *refname, const unsigned char *sha1, 370int find_current_ref(const char *refname, const unsigned char *sha1,
371 int flags, void *cb_data) 371 int flags, void *cb_data)
372{ 372{
373 struct refmatch *info; 373 struct refmatch *info;
374 374
375 info = (struct refmatch *)cb_data; 375 info = (struct refmatch *)cb_data;
376 if (!strcmp(refname, info->req_ref)) 376 if (!strcmp(refname, info->req_ref))
377 info->match = 1; 377 info->match = 1;
378 if (!info->first_ref) 378 if (!info->first_ref)
379 info->first_ref = xstrdup(refname); 379 info->first_ref = xstrdup(refname);
380 return info->match; 380 return info->match;
381} 381}
382 382
383char *find_default_branch(struct cgit_repo *repo) 383char *find_default_branch(struct cgit_repo *repo)
384{ 384{
385 struct refmatch info; 385 struct refmatch info;
386 char *ref; 386 char *ref;
387 387
388 info.req_ref = repo->defbranch; 388 info.req_ref = repo->defbranch;
389 info.first_ref = NULL; 389 info.first_ref = NULL;
390 info.match = 0; 390 info.match = 0;
391 for_each_branch_ref(find_current_ref, &info); 391 for_each_branch_ref(find_current_ref, &info);
392 if (info.match) 392 if (info.match)
393 ref = info.req_ref; 393 ref = info.req_ref;
394 else 394 else
395 ref = info.first_ref; 395 ref = info.first_ref;
396 if (ref) 396 if (ref)
397 ref = xstrdup(ref); 397 ref = xstrdup(ref);
398 return ref; 398 return ref;
399} 399}
400 400
401static int prepare_repo_cmd(struct cgit_context *ctx) 401static int prepare_repo_cmd(struct cgit_context *ctx)
402{ 402{
403 char *tmp; 403 char *tmp;
404 unsigned char sha1[20]; 404 unsigned char sha1[20];
405 int nongit = 0; 405 int nongit = 0;
406 int rc;
406 407
407 setenv("GIT_DIR", ctx->repo->path, 1); 408 setenv("GIT_DIR", ctx->repo->path, 1);
408 setup_git_directory_gently(&nongit); 409 setup_git_directory_gently(&nongit);
409 if (nongit) { 410 if (nongit) {
411 rc = errno;
410 ctx->page.title = fmt("%s - %s", ctx->cfg.root_title, 412 ctx->page.title = fmt("%s - %s", ctx->cfg.root_title,
411 "config error"); 413 "config error");
412 tmp = fmt("Not a git repository: '%s'", ctx->repo->path); 414 tmp = fmt("Failed to open %s: %s",
415 ctx->repo->name,
416 rc ? strerror(rc) : "Not a valid git repository");
413 ctx->repo = NULL; 417 ctx->repo = NULL;
414 cgit_print_http_headers(ctx); 418 cgit_print_http_headers(ctx);
415 cgit_print_docstart(ctx); 419 cgit_print_docstart(ctx);
416 cgit_print_pageheader(ctx); 420 cgit_print_pageheader(ctx);
417 cgit_print_error(tmp); 421 cgit_print_error(tmp);
418 cgit_print_docend(); 422 cgit_print_docend();
419 return 1; 423 return 1;
420 } 424 }
421 ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc); 425 ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc);
422 426
423 if (!ctx->qry.head) { 427 if (!ctx->qry.head) {
424 ctx->qry.nohead = 1; 428 ctx->qry.nohead = 1;
425 ctx->qry.head = find_default_branch(ctx->repo); 429 ctx->qry.head = find_default_branch(ctx->repo);
426 ctx->repo->defbranch = ctx->qry.head; 430 ctx->repo->defbranch = ctx->qry.head;
427 } 431 }
428 432
429 if (!ctx->qry.head) { 433 if (!ctx->qry.head) {
430 cgit_print_http_headers(ctx); 434 cgit_print_http_headers(ctx);
431 cgit_print_docstart(ctx); 435 cgit_print_docstart(ctx);
432 cgit_print_pageheader(ctx); 436 cgit_print_pageheader(ctx);
433 cgit_print_error("Repository seems to be empty"); 437 cgit_print_error("Repository seems to be empty");
434 cgit_print_docend(); 438 cgit_print_docend();
435 return 1; 439 return 1;
436 } 440 }
437 441
438 if (get_sha1(ctx->qry.head, sha1)) { 442 if (get_sha1(ctx->qry.head, sha1)) {
439 tmp = xstrdup(ctx->qry.head); 443 tmp = xstrdup(ctx->qry.head);
440 ctx->qry.head = ctx->repo->defbranch; 444 ctx->qry.head = ctx->repo->defbranch;
441 ctx->page.status = 404; 445 ctx->page.status = 404;
442 ctx->page.statusmsg = "not found"; 446 ctx->page.statusmsg = "not found";
443 cgit_print_http_headers(ctx); 447 cgit_print_http_headers(ctx);
444 cgit_print_docstart(ctx); 448 cgit_print_docstart(ctx);
445 cgit_print_pageheader(ctx); 449 cgit_print_pageheader(ctx);
446 cgit_print_error(fmt("Invalid branch: %s", tmp)); 450 cgit_print_error(fmt("Invalid branch: %s", tmp));
447 cgit_print_docend(); 451 cgit_print_docend();
448 return 1; 452 return 1;
449 } 453 }
450 return 0; 454 return 0;
451} 455}
452 456
453static void process_request(void *cbdata) 457static void process_request(void *cbdata)
454{ 458{
455 struct cgit_context *ctx = cbdata; 459 struct cgit_context *ctx = cbdata;
456 struct cgit_cmd *cmd; 460 struct cgit_cmd *cmd;
457 461
458 cmd = cgit_get_cmd(ctx); 462 cmd = cgit_get_cmd(ctx);
459 if (!cmd) { 463 if (!cmd) {
460 ctx->page.title = "cgit error"; 464 ctx->page.title = "cgit error";
461 cgit_print_http_headers(ctx); 465 cgit_print_http_headers(ctx);
462 cgit_print_docstart(ctx); 466 cgit_print_docstart(ctx);
463 cgit_print_pageheader(ctx); 467 cgit_print_pageheader(ctx);
464 cgit_print_error("Invalid request"); 468 cgit_print_error("Invalid request");
465 cgit_print_docend(); 469 cgit_print_docend();
466 return; 470 return;
467 } 471 }
468 472
469 /* If cmd->want_vpath is set, assume ctx->qry.path contains a "virtual" 473 /* If cmd->want_vpath is set, assume ctx->qry.path contains a "virtual"
470 * in-project path limit to be made available at ctx->qry.vpath. 474 * in-project path limit to be made available at ctx->qry.vpath.
471 * Otherwise, no path limit is in effect (ctx->qry.vpath = NULL). 475 * Otherwise, no path limit is in effect (ctx->qry.vpath = NULL).
472 */ 476 */
473 ctx->qry.vpath = cmd->want_vpath ? ctx->qry.path : NULL; 477 ctx->qry.vpath = cmd->want_vpath ? ctx->qry.path : NULL;
474 478
475 if (cmd->want_repo && !ctx->repo) { 479 if (cmd->want_repo && !ctx->repo) {
476 cgit_print_http_headers(ctx); 480 cgit_print_http_headers(ctx);
477 cgit_print_docstart(ctx); 481 cgit_print_docstart(ctx);
478 cgit_print_pageheader(ctx); 482 cgit_print_pageheader(ctx);
479 cgit_print_error(fmt("No repository selected")); 483 cgit_print_error(fmt("No repository selected"));
480 cgit_print_docend(); 484 cgit_print_docend();
481 return; 485 return;
482 } 486 }
483 487
484 if (ctx->repo && prepare_repo_cmd(ctx)) 488 if (ctx->repo && prepare_repo_cmd(ctx))
485 return; 489 return;
486 490
487 if (cmd->want_layout) { 491 if (cmd->want_layout) {
488 cgit_print_http_headers(ctx); 492 cgit_print_http_headers(ctx);
489 cgit_print_docstart(ctx); 493 cgit_print_docstart(ctx);
490 cgit_print_pageheader(ctx); 494 cgit_print_pageheader(ctx);
491 } 495 }
492 496
493 cmd->fn(ctx); 497 cmd->fn(ctx);
494 498
495 if (cmd->want_layout) 499 if (cmd->want_layout)
496 cgit_print_docend(); 500 cgit_print_docend();
497} 501}
498 502
499int cmp_repos(const void *a, const void *b) 503int cmp_repos(const void *a, const void *b)
500{ 504{
501 const struct cgit_repo *ra = a, *rb = b; 505 const struct cgit_repo *ra = a, *rb = b;
502 return strcmp(ra->url, rb->url); 506 return strcmp(ra->url, rb->url);
503} 507}
504 508
505char *build_snapshot_setting(int bitmap) 509char *build_snapshot_setting(int bitmap)
506{ 510{
507 const struct cgit_snapshot_format *f; 511 const struct cgit_snapshot_format *f;
508 char *result = xstrdup(""); 512 char *result = xstrdup("");