aboutsummaryrefslogtreecommitdiffstats
path: root/cgit.c
diff options
context:
space:
mode:
authorGravatar John Keeping <john@keeping.me.uk>2013-04-06 18:28:57 (JST)
committerGravatar Jason A. Donenfeld <Jason@zx2c4.com>2013-04-08 23:12:52 (JST)
commitfb3655df3bf85bd405c5921bbd4b3a54c705c839 (patch)
tree419a962a0b82f5ba3023791549044ff462229250 /cgit.c
parent42d5476f258e7909682f1b611da00d64507d45c6 (diff)
downloadcgit-fb3655df3bf85bd405c5921bbd4b3a54c705c839.zip
cgit-fb3655df3bf85bd405c5921bbd4b3a54c705c839.tar.gz
use struct strbuf instead of static buffers
Use "struct strbuf" from Git to remove the limit on file path length. Notes on scan-tree: This is slightly involved since I decided to pass the strbuf into add_repo() and modify if whenever a new file name is required, which should avoid any extra allocations within that function. The pattern there is to append the filename, use it and then reset the buffer to its original length (retaining a trailing '/'). Notes on ui-snapshot: Since write_archive modifies the argv array passed to it we copy the argv_array values into a new array of char* and then free the original argv_array structure and the new array without worrying about what the values now look like. Signed-off-by: John Keeping <john@keeping.me.uk>
Diffstat (limited to 'cgit.c')
-rw-r--r--cgit.c72
1 files changed, 36 insertions, 36 deletions
diff --git a/cgit.c b/cgit.c
index 4e51283..f73c7b0 100644
--- a/cgit.c
+++ b/cgit.c
@@ -468,8 +468,8 @@ static int prepare_repo_cmd(struct cgit_context *ctx)
468 if (nongit) { 468 if (nongit) {
469 const char *name = ctx->repo->name; 469 const char *name = ctx->repo->name;
470 rc = errno; 470 rc = errno;
471 ctx->page.title = fmt("%s - %s", ctx->cfg.root_title, 471 ctx->page.title = fmtalloc("%s - %s", ctx->cfg.root_title,
472 "config error"); 472 "config error");
473 ctx->repo = NULL; 473 ctx->repo = NULL;
474 cgit_print_http_headers(ctx); 474 cgit_print_http_headers(ctx);
475 cgit_print_docstart(ctx); 475 cgit_print_docstart(ctx);
@@ -479,7 +479,7 @@ static int prepare_repo_cmd(struct cgit_context *ctx)
479 cgit_print_docend(); 479 cgit_print_docend();
480 return 1; 480 return 1;
481 } 481 }
482 ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc); 482 ctx->page.title = fmtalloc("%s - %s", ctx->repo->name, ctx->repo->desc);
483 483
484 if (!ctx->repo->defbranch) 484 if (!ctx->repo->defbranch)
485 ctx->repo->defbranch = guess_defbranch(); 485 ctx->repo->defbranch = guess_defbranch();
@@ -577,21 +577,16 @@ static int cmp_repos(const void *a, const void *b)
577static char *build_snapshot_setting(int bitmap) 577static char *build_snapshot_setting(int bitmap)
578{ 578{
579 const struct cgit_snapshot_format *f; 579 const struct cgit_snapshot_format *f;
580 char *result = xstrdup(""); 580 struct strbuf result = STRBUF_INIT;
581 char *tmp;
582 int len;
583 581
584 for (f = cgit_snapshot_formats; f->suffix; f++) { 582 for (f = cgit_snapshot_formats; f->suffix; f++) {
585 if (f->bit & bitmap) { 583 if (f->bit & bitmap) {
586 tmp = result; 584 if (result.len)
587 result = xstrdup(fmt("%s%s ", tmp, f->suffix)); 585 strbuf_addch(&result, ' ');
588 free(tmp); 586 strbuf_addstr(&result, f->suffix);
589 } 587 }
590 } 588 }
591 len = strlen(result); 589 return strbuf_detach(&result, NULL);
592 if (len)
593 result[len - 1] = '\0';
594 return result;
595} 590}
596 591
597static char *get_first_line(char *txt) 592static char *get_first_line(char *txt)
@@ -639,7 +634,7 @@ static void print_repo(FILE *f, struct cgit_repo *repo)
639 fprintf(f, "repo.source-filter=%s\n", repo->source_filter->cmd); 634 fprintf(f, "repo.source-filter=%s\n", repo->source_filter->cmd);
640 if (repo->snapshots != ctx.cfg.snapshots) { 635 if (repo->snapshots != ctx.cfg.snapshots) {
641 char *tmp = build_snapshot_setting(repo->snapshots); 636 char *tmp = build_snapshot_setting(repo->snapshots);
642 fprintf(f, "repo.snapshots=%s\n", tmp); 637 fprintf(f, "repo.snapshots=%s\n", tmp ? tmp : "");
643 free(tmp); 638 free(tmp);
644 } 639 }
645 if (repo->max_stats != ctx.cfg.max_stats) 640 if (repo->max_stats != ctx.cfg.max_stats)
@@ -661,20 +656,22 @@ static void print_repolist(FILE *f, struct cgit_repolist *list, int start)
661 */ 656 */
662static int generate_cached_repolist(const char *path, const char *cached_rc) 657static int generate_cached_repolist(const char *path, const char *cached_rc)
663{ 658{
664 char *locked_rc; 659 struct strbuf locked_rc = STRBUF_INIT;
660 int result = 0;
665 int idx; 661 int idx;
666 FILE *f; 662 FILE *f;
667 663
668 locked_rc = xstrdup(fmt("%s.lock", cached_rc)); 664 strbuf_addf(&locked_rc, "%s.lock", cached_rc);
669 f = fopen(locked_rc, "wx"); 665 f = fopen(locked_rc.buf, "wx");
670 if (!f) { 666 if (!f) {
671 /* Inform about the error unless the lockfile already existed, 667 /* Inform about the error unless the lockfile already existed,
672 * since that only means we've got concurrent requests. 668 * since that only means we've got concurrent requests.
673 */ 669 */
674 if (errno != EEXIST) 670 result = errno;
671 if (result != EEXIST)
675 fprintf(stderr, "[cgit] Error opening %s: %s (%d)\n", 672 fprintf(stderr, "[cgit] Error opening %s: %s (%d)\n",
676 locked_rc, strerror(errno), errno); 673 locked_rc.buf, strerror(result), result);
677 return errno; 674 goto out;
678 } 675 }
679 idx = cgit_repolist.count; 676 idx = cgit_repolist.count;
680 if (ctx.cfg.project_list) 677 if (ctx.cfg.project_list)
@@ -682,55 +679,59 @@ static int generate_cached_repolist(const char *path, const char *cached_rc)
682 else 679 else
683 scan_tree(path, repo_config); 680 scan_tree(path, repo_config);
684 print_repolist(f, &cgit_repolist, idx); 681 print_repolist(f, &cgit_repolist, idx);
685 if (rename(locked_rc, cached_rc)) 682 if (rename(locked_rc.buf, cached_rc))
686 fprintf(stderr, "[cgit] Error renaming %s to %s: %s (%d)\n", 683 fprintf(stderr, "[cgit] Error renaming %s to %s: %s (%d)\n",
687 locked_rc, cached_rc, strerror(errno), errno); 684 locked_rc.buf, cached_rc, strerror(errno), errno);
688 fclose(f); 685 fclose(f);
689 return 0; 686out:
687 strbuf_release(&locked_rc);
688 return result;
690} 689}
691 690
692static void process_cached_repolist(const char *path) 691static void process_cached_repolist(const char *path)
693{ 692{
694 struct stat st; 693 struct stat st;
695 char *cached_rc; 694 struct strbuf cached_rc = STRBUF_INIT;
696 time_t age; 695 time_t age;
697 unsigned long hash; 696 unsigned long hash;
698 697
699 hash = hash_str(path); 698 hash = hash_str(path);
700 if (ctx.cfg.project_list) 699 if (ctx.cfg.project_list)
701 hash += hash_str(ctx.cfg.project_list); 700 hash += hash_str(ctx.cfg.project_list);
702 cached_rc = xstrdup(fmt("%s/rc-%8lx", ctx.cfg.cache_root, hash)); 701 strbuf_addf(&cached_rc, "%s/rc-%8lx", ctx.cfg.cache_root, hash);
703 702
704 if (stat(cached_rc, &st)) { 703 if (stat(cached_rc.buf, &st)) {
705 /* Nothing is cached, we need to scan without forking. And 704 /* Nothing is cached, we need to scan without forking. And
706 * if we fail to generate a cached repolist, we need to 705 * if we fail to generate a cached repolist, we need to
707 * invoke scan_tree manually. 706 * invoke scan_tree manually.
708 */ 707 */
709 if (generate_cached_repolist(path, cached_rc)) { 708 if (generate_cached_repolist(path, cached_rc.buf)) {
710 if (ctx.cfg.project_list) 709 if (ctx.cfg.project_list)
711 scan_projects(path, ctx.cfg.project_list, 710 scan_projects(path, ctx.cfg.project_list,
712 repo_config); 711 repo_config);
713 else 712 else
714 scan_tree(path, repo_config); 713 scan_tree(path, repo_config);
715 } 714 }
716 return; 715 goto out;
717 } 716 }
718 717
719 parse_configfile(cached_rc, config_cb); 718 parse_configfile(cached_rc.buf, config_cb);
720 719
721 /* If the cached configfile hasn't expired, lets exit now */ 720 /* If the cached configfile hasn't expired, lets exit now */
722 age = time(NULL) - st.st_mtime; 721 age = time(NULL) - st.st_mtime;
723 if (age <= (ctx.cfg.cache_scanrc_ttl * 60)) 722 if (age <= (ctx.cfg.cache_scanrc_ttl * 60))
724 return; 723 goto out;
725 724
726 /* The cached repolist has been parsed, but it was old. So lets 725 /* The cached repolist has been parsed, but it was old. So lets
727 * rescan the specified path and generate a new cached repolist 726 * rescan the specified path and generate a new cached repolist
728 * in a child-process to avoid latency for the current request. 727 * in a child-process to avoid latency for the current request.
729 */ 728 */
730 if (fork()) 729 if (fork())
731 return; 730 goto out;
732 731
733 exit(generate_cached_repolist(path, cached_rc)); 732 exit(generate_cached_repolist(path, cached_rc.buf));
733out:
734 strbuf_release(&cached_rc);
734} 735}
735 736
736static void cgit_parse_args(int argc, const char **argv) 737static void cgit_parse_args(int argc, const char **argv)
@@ -812,7 +813,6 @@ static int calc_ttl()
812int main(int argc, const char **argv) 813int main(int argc, const char **argv)
813{ 814{
814 const char *path; 815 const char *path;
815 char *qry;
816 int err, ttl; 816 int err, ttl;
817 817
818 prepare_context(&ctx); 818 prepare_context(&ctx);
@@ -843,9 +843,9 @@ int main(int argc, const char **argv)
843 path++; 843 path++;
844 ctx.qry.url = xstrdup(path); 844 ctx.qry.url = xstrdup(path);
845 if (ctx.qry.raw) { 845 if (ctx.qry.raw) {
846 qry = ctx.qry.raw; 846 char *newqry = fmtalloc("%s?%s", path, ctx.qry.raw);
847 ctx.qry.raw = xstrdup(fmt("%s?%s", path, qry)); 847 free(ctx.qry.raw);
848 free(qry); 848 ctx.qry.raw = newqry;
849 } else 849 } else
850 ctx.qry.raw = xstrdup(ctx.qry.url); 850 ctx.qry.raw = xstrdup(ctx.qry.url);
851 cgit_parse_url(ctx.qry.url); 851 cgit_parse_url(ctx.qry.url);