| -rw-r--r-- | cache.c | 57 | ||||
| -rw-r--r-- | cgit.c | 72 | ||||
| -rw-r--r-- | scan-tree.c | 160 | ||||
| -rw-r--r-- | ui-log.c | 33 | ||||
| -rw-r--r-- | ui-plain.c | 6 | ||||
| -rw-r--r-- | ui-refs.c | 10 | ||||
| -rw-r--r-- | ui-repolist.c | 28 | ||||
| -rw-r--r-- | ui-shared.c | 63 | ||||
| -rw-r--r-- | ui-snapshot.c | 60 | ||||
| -rw-r--r-- | ui-summary.c | 12 | ||||
| -rw-r--r-- | ui-tag.c | 14 | ||||
| -rw-r--r-- | ui-tree.c | 33 |
12 files changed, 243 insertions, 305 deletions
@@ -312,9 +312,9 @@ int cache_process(int size, const char *path, const char *key, int ttl, cache_fill_fn fn, void *cbdata) { unsigned long hash; - int i; - struct strbuf filename = STRBUF_INIT; - struct strbuf lockname = STRBUF_INIT; + int len, i; + char filename[1024]; + char lockname[1024 + 5]; /* 5 = ".lock" */ struct cache_slot slot; /* If the cache is disabled, just generate the content */ @@ -329,22 +329,32 @@ int cache_process(int size, const char *path, const char *key, int ttl, fn(cbdata); return 0; } + len = strlen(path); + if (len > sizeof(filename) - 10) { /* 10 = "/01234567\0" */ + cache_log("[cgit] Cache path too long, caching is disabled: %s\n", + path); + fn(cbdata); + return 0; + } if (!key) key = ""; hash = hash_str(key) % size; - strbuf_addstr(&filename, path); - strbuf_ensure_end(&filename, '/'); + strcpy(filename, path); + if (filename[len - 1] != '/') + filename[len++] = '/'; for (i = 0; i < 8; i++) { - strbuf_addf(&filename, "%x", (unsigned char)(hash & 0xf)); + sprintf(filename + len++, "%x", + (unsigned char)(hash & 0xf)); hash >>= 4; } - strbuf_addbuf(&lockname, &filename); - strbuf_addstr(&lockname, ".lock"); + filename[len] = '\0'; + strcpy(lockname, filename); + strcpy(lockname + len, ".lock"); slot.fn = fn; slot.cbdata = cbdata; slot.ttl = ttl; - slot.cache_name = strbuf_detach(&filename, NULL); - slot.lock_name = strbuf_detach(&lockname, NULL); + slot.cache_name = filename; + slot.lock_name = lockname; slot.key = key; slot.keylen = strlen(key); return process_slot(&slot); @@ -371,13 +381,18 @@ int cache_ls(const char *path) struct dirent *ent; int err = 0; struct cache_slot slot; - struct strbuf fullname = STRBUF_INIT; - size_t prefixlen; + char fullname[1024]; + char *name; if (!path) { cache_log("[cgit] cache path not specified\n"); return -1; } + if (strlen(path) > 1024 - 10) { + cache_log("[cgit] cache path too long: %s\n", + path); + return -1; + } dir = opendir(path); if (!dir) { err = errno; @@ -385,28 +400,30 @@ int cache_ls(const char *path) path, strerror(err), err); return err; } - strbuf_addstr(&fullname, path); - strbuf_ensure_end(&fullname, '/'); - prefixlen = fullname.len; + strcpy(fullname, path); + name = fullname + strlen(path); + if (*(name - 1) != '/') { + *name++ = '/'; + *name = '\0'; + } + slot.cache_name = fullname; while ((ent = readdir(dir)) != NULL) { if (strlen(ent->d_name) != 8) continue; - strbuf_setlen(&fullname, prefixlen); - strbuf_addstr(&fullname, ent->d_name); + strcpy(name, ent->d_name); if ((err = open_slot(&slot)) != 0) { cache_log("[cgit] unable to open path %s: %s (%d)\n", - fullname.buf, strerror(err), err); + fullname, strerror(err), err); continue; } printf("%s %s %10"PRIuMAX" %s\n", - fullname.buf, + name, sprintftime("%Y-%m-%d %H:%M:%S", slot.cache_st.st_mtime), (uintmax_t)slot.cache_st.st_size, slot.buf); close_slot(&slot); } - slot.cache_name = strbuf_detach(&fullname, NULL); closedir(dir); return 0; } @@ -468,8 +468,8 @@ static int prepare_repo_cmd(struct cgit_context *ctx) if (nongit) { const char *name = ctx->repo->name; rc = errno; - ctx->page.title = fmtalloc("%s - %s", ctx->cfg.root_title, - "config error"); + ctx->page.title = fmt("%s - %s", ctx->cfg.root_title, + "config error"); ctx->repo = NULL; cgit_print_http_headers(ctx); cgit_print_docstart(ctx); @@ -479,7 +479,7 @@ static int prepare_repo_cmd(struct cgit_context *ctx) cgit_print_docend(); return 1; } - ctx->page.title = fmtalloc("%s - %s", ctx->repo->name, ctx->repo->desc); + ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc); if (!ctx->repo->defbranch) ctx->repo->defbranch = guess_defbranch(); @@ -577,16 +577,21 @@ static int cmp_repos(const void *a, const void *b) static char *build_snapshot_setting(int bitmap) { const struct cgit_snapshot_format *f; - struct strbuf result = STRBUF_INIT; + char *result = xstrdup(""); + char *tmp; + int len; for (f = cgit_snapshot_formats; f->suffix; f++) { if (f->bit & bitmap) { - if (result.len) - strbuf_addch(&result, ' '); - strbuf_addstr(&result, f->suffix); + tmp = result; + result = xstrdup(fmt("%s%s ", tmp, f->suffix)); + free(tmp); } } - return strbuf_detach(&result, NULL); + len = strlen(result); + if (len) + result[len - 1] = '\0'; + return result; } static char *get_first_line(char *txt) @@ -634,7 +639,7 @@ static void print_repo(FILE *f, struct cgit_repo *repo) fprintf(f, "repo.source-filter=%s\n", repo->source_filter->cmd); if (repo->snapshots != ctx.cfg.snapshots) { char *tmp = build_snapshot_setting(repo->snapshots); - fprintf(f, "repo.snapshots=%s\n", tmp ? tmp : ""); + fprintf(f, "repo.snapshots=%s\n", tmp); free(tmp); } if (repo->max_stats != ctx.cfg.max_stats) @@ -656,22 +661,20 @@ static void print_repolist(FILE *f, struct cgit_repolist *list, int start) */ static int generate_cached_repolist(const char *path, const char *cached_rc) { - struct strbuf locked_rc = STRBUF_INIT; - int result = 0; + char *locked_rc; int idx; FILE *f; - strbuf_addf(&locked_rc, "%s.lock", cached_rc); - f = fopen(locked_rc.buf, "wx"); + locked_rc = xstrdup(fmt("%s.lock", cached_rc)); + f = fopen(locked_rc, "wx"); if (!f) { /* Inform about the error unless the lockfile already existed, * since that only means we've got concurrent requests. */ - result = errno; - if (result != EEXIST) + if (errno != EEXIST) fprintf(stderr, "[cgit] Error opening %s: %s (%d)\n", - locked_rc.buf, strerror(result), result); - goto out; + locked_rc, strerror(errno), errno); + return errno; } idx = cgit_repolist.count; if (ctx.cfg.project_list) @@ -679,59 +682,55 @@ static int generate_cached_repolist(const char *path, const char *cached_rc) else scan_tree(path, repo_config); print_repolist(f, &cgit_repolist, idx); - if (rename(locked_rc.buf, cached_rc)) + if (rename(locked_rc, cached_rc)) fprintf(stderr, "[cgit] Error renaming %s to %s: %s (%d)\n", - locked_rc.buf, cached_rc, strerror(errno), errno); + locked_rc, cached_rc, strerror(errno), errno); fclose(f); -out: - strbuf_release(&locked_rc); - return result; + return 0; } static void process_cached_repolist(const char *path) { struct stat st; - struct strbuf cached_rc = STRBUF_INIT; + char *cached_rc; time_t age; unsigned long hash; hash = hash_str(path); if (ctx.cfg.project_list) hash += hash_str(ctx.cfg.project_list); - strbuf_addf(&cached_rc, "%s/rc-%8lx", ctx.cfg.cache_root, hash); + cached_rc = xstrdup(fmt("%s/rc-%8lx", ctx.cfg.cache_root, hash)); - if (stat(cached_rc.buf, &st)) { + if (stat(cached_rc, &st)) { /* Nothing is cached, we need to scan without forking. And * if we fail to generate a cached repolist, we need to * invoke scan_tree manually. */ - if (generate_cached_repolist(path, cached_rc.buf)) { + if (generate_cached_repolist(path, cached_rc)) { if (ctx.cfg.project_list) scan_projects(path, ctx.cfg.project_list, repo_config); else scan_tree(path, repo_config); } - goto out; + return; } - parse_configfile(cached_rc.buf, config_cb); + parse_configfile(cached_rc, config_cb); /* If the cached configfile hasn't expired, lets exit now */ age = time(NULL) - st.st_mtime; if (age <= (ctx.cfg.cache_scanrc_ttl * 60)) - goto out; + return; /* The cached repolist has been parsed, but it was old. So lets * rescan the specified path and generate a new cached repolist * in a child-process to avoid latency for the current request. */ if (fork()) - goto out; + return; - exit(generate_cached_repolist(path, cached_rc.buf)); -out: - strbuf_release(&cached_rc); + exit(generate_cached_repolist(path, cached_rc)); } static void cgit_parse_args(int argc, const char **argv) @@ -813,6 +812,7 @@ static int calc_ttl() int main(int argc, const char **argv) { const char *path; + char *qry; int err, ttl; prepare_context(&ctx); @@ -843,9 +843,9 @@ int main(int argc, const char **argv) path++; ctx.qry.url = xstrdup(path); if (ctx.qry.raw) { - char *newqry = fmtalloc("%s?%s", path, ctx.qry.raw); - free(ctx.qry.raw); - ctx.qry.raw = newqry; + qry = ctx.qry.raw; + ctx.qry.raw = xstrdup(fmt("%s?%s", path, qry)); + free(qry); } else ctx.qry.raw = xstrdup(ctx.qry.url); cgit_parse_url(ctx.qry.url); diff --git a/scan-tree.c b/scan-tree.c index beb584b..05caba5 100644 --- a/scan-tree.c +++ b/scan-tree.c @@ -12,38 +12,38 @@ #include "configfile.h" #include "html.h" +#define MAX_PATH 4096 + /* return 1 if path contains a objects/ directory and a HEAD file */ static int is_git_dir(const char *path) { struct stat st; - struct strbuf pathbuf = STRBUF_INIT; - int result = 0; + static char buf[MAX_PATH]; - strbuf_addf(&pathbuf, "%s/objects", path); - if (stat(pathbuf.buf, &st)) { + if (snprintf(buf, MAX_PATH, "%s/objects", path) >= MAX_PATH) { + fprintf(stderr, "Insanely long path: %s\n", path); + return 0; + } + if (stat(buf, &st)) { if (errno != ENOENT) fprintf(stderr, "Error checking path %s: %s (%d)\n", path, strerror(errno), errno); - goto out; + return 0; } if (!S_ISDIR(st.st_mode)) - goto out; + return 0; - strbuf_reset(&pathbuf); - strbuf_addf(&pathbuf, "%s/HEAD", path); - if (stat(pathbuf.buf, &st)) { + sprintf(buf, "%s/HEAD", path); + if (stat(buf, &st)) { if (errno != ENOENT) fprintf(stderr, "Error checking path %s: %s (%d)\n", path, strerror(errno), errno); - goto out; + return 0; } if (!S_ISREG(st.st_mode)) - goto out; + return 0; - result = 1; -out: - strbuf_release(&pathbuf); - return result; + return 1; } struct cgit_repo *repo; @@ -75,61 +75,47 @@ static char *xstrrchr(char *s, char *from, int c) return from < s ? NULL : from; } -static void add_repo(const char *base, struct strbuf *path, repo_config_fn fn) +static void add_repo(const char *base, const char *path, repo_config_fn fn) { struct stat st; struct passwd *pwd; - size_t pathlen; - struct strbuf rel = STRBUF_INIT; - char *p, *slash; + char *rel, *p, *slash; int n; size_t size; - if (stat(path->buf, &st)) { + if (stat(path, &st)) { fprintf(stderr, "Error accessing %s: %s (%d)\n", - path->buf, strerror(errno), errno); + path, strerror(errno), errno); return; } - strbuf_addch(path, '/'); - pathlen = path->len; - - if (ctx.cfg.strict_export) { - strbuf_addstr(path, ctx.cfg.strict_export); - if(stat(path->buf, &st)) - return; - strbuf_setlen(path, pathlen); - } + if (ctx.cfg.strict_export && stat(fmt("%s/%s", path, ctx.cfg.strict_export), &st)) + return; - strbuf_addstr(path, "noweb"); - if (!stat(path->buf, &st)) + if (!stat(fmt("%s/noweb", path), &st)) return; - strbuf_setlen(path, pathlen); - if (strncmp(base, path->buf, strlen(base))) - strbuf_addbuf(&rel, path); + if (base == path) + rel = xstrdup(path); else - strbuf_addstr(&rel, path->buf + strlen(base) + 1); + rel = xstrdup(path + strlen(base) + 1); - if (!strcmp(rel.buf + rel.len - 5, "/.git")) - strbuf_setlen(&rel, rel.len - 5); + if (!strcmp(rel + strlen(rel) - 5, "/.git")) + rel[strlen(rel) - 5] = '\0'; - repo = cgit_add_repo(rel.buf); + repo = cgit_add_repo(rel); config_fn = fn; - if (ctx.cfg.enable_git_config) { - strbuf_addstr(path, "config"); - git_config_from_file(gitconfig_config, path->buf, NULL); - strbuf_setlen(path, pathlen); - } + if (ctx.cfg.enable_git_config) + git_config_from_file(gitconfig_config, fmt("%s/config", path), NULL); if (ctx.cfg.remove_suffix) if ((p = strrchr(repo->url, '.')) && !strcmp(p, ".git")) *p = '\0'; - repo->path = xstrdup(path->buf); + repo->path = xstrdup(path); while (!repo->owner) { if ((pwd = getpwuid(st.st_uid)) == NULL) { fprintf(stderr, "Error reading owner-info for %s: %s (%d)\n", - path->buf, strerror(errno), errno); + path, strerror(errno), errno); break; } if (pwd->pw_gecos) @@ -139,32 +125,30 @@ static void add_repo(const char *base, struct strbuf *path, repo_config_fn fn) } if (repo->desc == cgit_default_repo_desc || !repo->desc) { - strbuf_addstr(path, "description"); - if (!stat(path->buf, &st)) - readfile(path->buf, &repo->desc, &size); - strbuf_setlen(path, pathlen); + p = fmt("%s/description", path); + if (!stat(p, &st)) + readfile(p, &repo->desc, &size); } if (!repo->readme) { - strbuf_addstr(path, "README.html"); - if (!stat(path->buf, &st)) + p = fmt("%s/README.html", path); + if (!stat(p, &st)) repo->readme = "README.html"; - strbuf_setlen(path, pathlen); } if (ctx.cfg.section_from_path) { n = ctx.cfg.section_from_path; if (n > 0) { - slash = rel.buf; + slash = rel; while (slash && n && (slash = strchr(slash, '/'))) n--; } else { - slash = rel.buf + rel.len; - while (slash && n && (slash = xstrrchr(rel.buf, slash, '/'))) + slash = rel + strlen(rel); + while (slash && n && (slash = xstrrchr(rel, slash, '/'))) n++; } if (slash && !n) { *slash = '\0'; - repo->section = xstrdup(rel.buf); + repo->section = xstrdup(rel); *slash = '/'; if (!prefixcmp(repo->name, repo->section)) { repo->name += strlen(repo->section); @@ -174,19 +158,19 @@ static void add_repo(const char *base, struct strbuf *path, repo_config_fn fn) } } - strbuf_addstr(path, "cgitrc"); - if (!stat(path->buf, &st)) - parse_configfile(xstrdup(path->buf), &repo_config); + p = fmt("%s/cgitrc", path); + if (!stat(p, &st)) + parse_configfile(xstrdup(p), &repo_config); + - strbuf_release(&rel); + free(rel); } static void scan_path(const char *base, const char *path, repo_config_fn fn) { DIR *dir = opendir(path); struct dirent *ent; - struct strbuf pathbuf = STRBUF_INIT; - size_t pathlen = strlen(path); + char *buf; struct stat st; if (!dir) { @@ -194,22 +178,14 @@ static void scan_path(const char *base, const char *path, repo_config_fn fn) path, strerror(errno), errno); return; } - - strbuf_add(&pathbuf, path, strlen(path)); - if (is_git_dir(pathbuf.buf)) { - add_repo(base, &pathbuf, fn); + if (is_git_dir(path)) { + add_repo(base, path, fn); goto end; } - strbuf_addstr(&pathbuf, "/.git"); - if (is_git_dir(pathbuf.buf)) { - add_repo(base, &pathbuf, fn); + if (is_git_dir(fmt("%s/.git", path))) { + add_repo(base, fmt("%s/.git", path), fn); goto end; } - /* - * Add one because we don't want to lose the trailing '/' when we - * reset the length of pathbuf in the loop below. - */ - pathlen++; while ((ent = readdir(dir)) != NULL) { if (ent->d_name[0] == '.') { if (ent->d_name[1] == '\0') @@ -219,18 +195,24 @@ static void scan_path(const char *base, const char *path, repo_config_fn fn) if (!ctx.cfg.scan_hidden_path) continue; } - strbuf_setlen(&pathbuf, pathlen); - strbuf_addstr(&pathbuf, ent->d_name); - if (stat(pathbuf.buf, &st)) { + buf = malloc(strlen(path) + strlen(ent->d_name) + 2); + if (!buf) { + fprintf(stderr, "Alloc error on %s: %s (%d)\n", + path, strerror(errno), errno); + exit(1); + } + sprintf(buf, "%s/%s", path, ent->d_name); + if (stat(buf, &st)) { fprintf(stderr, "Error checking path %s: %s (%d)\n", - pathbuf.buf, strerror(errno), errno); + buf, strerror(errno), errno); + free(buf); continue; } if (S_ISDIR(st.st_mode)) - scan_path(base, pathbuf.buf, fn); + scan_path(base, buf, fn); + free(buf); } end: - strbuf_release(&pathbuf); closedir(dir); } @@ -238,7 +220,7 @@ end: void scan_projects(const char *path, const char *projectsfile, repo_config_fn fn) { - struct strbuf line = STRBUF_INIT; + char line[MAX_PATH * 2], *z; FILE *projects; int err; @@ -248,19 +230,19 @@ void scan_projects(const char *path, const char *projectsfile, repo_config_fn fn projectsfile, strerror(errno), errno); return; } - while (strbuf_getline(&line, projects, '\n') != EOF) { - if (!line.len) - continue; - strbuf_insert(&line, 0, "/", 1); - strbuf_insert(&line, 0, path, strlen(path)); - scan_path(path, line.buf, fn); + while (fgets(line, sizeof(line), projects) != NULL) { + for (z = &lastc(line); + strlen(line) && strchr("\n\r", *z); + z = &lastc(line)) + *z = '\0'; + if (strlen(line)) + scan_path(path, fmt("%s/%s", path, line), fn); } if ((err = ferror(projects))) { fprintf(stderr, "Error reading from projectsfile %s: %s (%d)\n", projectsfile, strerror(err), err); } fclose(projects); - strbuf_release(&line); } void scan_tree(const char *path, repo_config_fn fn) @@ -243,19 +243,15 @@ static void print_commit(struct commit *commit, struct rev_info *revs) cgit_free_commitinfo(info); } -static const char *disambiguate_ref(const char *ref, int *must_free_result) +static const char *disambiguate_ref(const char *ref) { unsigned char sha1[20]; - struct strbuf longref = STRBUF_INIT; + const char *longref; - strbuf_addf(&longref, "refs/heads/%s", ref); - if (get_sha1(longref.buf, sha1) == 0) { - *must_free_result = 1; - return strbuf_detach(&longref, NULL); - } + longref = fmt("refs/heads/%s", ref); + if (get_sha1(longref, sha1) == 0) + return longref; - *must_free_result = 0; - strbuf_release(&longref); return ref; } @@ -288,26 +284,24 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern struct commit *commit; struct vector vec = VECTOR_INIT(char *); int i, columns = commit_graph ? 4 : 3; - int must_free_tip = 0; - struct strbuf argbuf = STRBUF_INIT; + char *arg; /* First argv is NULL */ vector_push(&vec, NULL, 0); if (!tip) tip = ctx.qry.head; - tip = disambiguate_ref(tip, &must_free_tip); + tip = disambiguate_ref(tip); vector_push(&vec, &tip, 0); if (grep && pattern && *pattern) { pattern = xstrdup(pattern); if (!strcmp(grep, "grep") || !strcmp(grep, "author") || !strcmp(grep, "committer")) { - strbuf_addf(&argbuf, "--%s=%s", grep, pattern); - vector_push(&vec, &argbuf.buf, 0); + arg = fmt("--%s=%s", grep, pattern); + vector_push(&vec, &arg, 0); } if (!strcmp(grep, "range")) { - char *arg; /* Split the pattern at whitespace and add each token * as a revision expression. Do not accept other * rev-list options. Also, replace the previously @@ -342,8 +336,8 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern } if (path) { - static const char *double_dash_arg = "--"; - vector_push(&vec, &double_dash_arg, 0); + arg = "--"; + vector_push(&vec, &arg, 0); vector_push(&vec, &path, 0); } @@ -436,9 +430,4 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern ctx.qry.vpath, 0, NULL, NULL, ctx.qry.showmsg); html("</td></tr>\n"); } - - /* If we allocated tip then it is safe to cast away const. */ - if (must_free_tip) - free((char*) tip); - strbuf_release(&argbuf); } @@ -109,9 +109,9 @@ static int print_object(const unsigned char *sha1, const char *path) static char *buildpath(const char *base, int baselen, const char *path) { if (path[0]) - return fmtalloc("%.*s%s/", baselen, base, path); + return fmt("%.*s%s/", baselen, base, path); else - return fmtalloc("%.*s/", baselen, base); + return fmt("%.*s/", baselen, base); } static void print_dir(const unsigned char *sha1, const char *base, @@ -142,7 +142,6 @@ static void print_dir(const unsigned char *sha1, const char *base, fullpath); html("</li>\n"); } - free(fullpath); } static void print_dir_entry(const unsigned char *sha1, const char *base, @@ -160,7 +159,6 @@ static void print_dir_entry(const unsigned char *sha1, const char *base, cgit_plain_link(path, NULL, NULL, ctx.qry.head, ctx.qry.sha1, fullpath); html("</li>\n"); - free(fullpath); } static void print_dir_tail(void) @@ -99,7 +99,7 @@ static void print_tag_header() static void print_tag_downloads(const struct cgit_repo *repo, const char *ref) { const struct cgit_snapshot_format* f; - struct strbuf filename = STRBUF_INIT; + char *filename; const char *basename; int free_ref = 0; @@ -111,7 +111,7 @@ static void print_tag_downloads(const struct cgit_repo *repo, const char *ref) if ((ref[0] == 'v' || ref[0] == 'V') && isdigit(ref[1])) ref++; if (isdigit(ref[0])) { - ref = fmtalloc("%s-%s", basename, ref); + ref = xstrdup(fmt("%s-%s", basename, ref)); free_ref = 1; } } @@ -119,15 +119,13 @@ static void print_tag_downloads(const struct cgit_repo *repo, const char *ref) for (f = cgit_snapshot_formats; f->suffix; f++) { if (!(repo->snapshots & f->bit)) continue; - strbuf_reset(&filename); - strbuf_addf(&filename, "%s%s", ref, f->suffix); - cgit_snapshot_link(filename.buf, NULL, NULL, NULL, NULL, filename.buf); + filename = fmt("%s%s", ref, f->suffix); + cgit_snapshot_link(filename, NULL, NULL, NULL, NULL, filename); html(" "); } if (free_ref) free((char *)ref); - strbuf_release(&filename); } static int print_tag(struct refinfo *ref) diff --git a/ui-repolist.c b/ui-repolist.c index 47ca997..76fe71a 100644 --- a/ui-repolist.c +++ b/ui-repolist.c @@ -33,7 +33,7 @@ static time_t read_agefile(char *path) static int get_repo_modtime(const struct cgit_repo *repo, time_t *mtime) { - struct strbuf path = STRBUF_INIT; + char *path; struct stat s; struct cgit_repo *r = (struct cgit_repo *)repo; @@ -41,36 +41,32 @@ static int get_repo_modtime(const struct cgit_repo *repo, time_t *mtime) *mtime = repo->mtime; return 1; } - strbuf_addf(&path, "%s/%s", repo->path, ctx.cfg.agefile); - if (stat(path.buf, &s) == 0) { - *mtime = read_agefile(path.buf); + path = fmt("%s/%s", repo->path, ctx.cfg.agefile); + if (stat(path, &s) == 0) { + *mtime = read_agefile(path); if (*mtime) { r->mtime = *mtime; - goto end; + return 1; } } - strbuf_reset(&path); - strbuf_addf(&path, "%s/refs/heads/%s", repo->path, - repo->defbranch ? repo->defbranch : "master"); - if (stat(path.buf, &s) == 0) { + path = fmt("%s/refs/heads/%s", repo->path, repo->defbranch ? + repo->defbranch : "master"); + if (stat(path, &s) == 0) { *mtime = s.st_mtime; r->mtime = *mtime; - goto end; + return 1; } - strbuf_reset(&path); - strbuf_addf(&path, "%s/%s", repo->path, "packed-refs"); - if (stat(path.buf, &s) == 0) { + path = fmt("%s/%s", repo->path, "packed-refs"); + if (stat(path, &s) == 0) { *mtime = s.st_mtime; r->mtime = *mtime; - goto end; + return 1; } *mtime = 0; r->mtime = *mtime; -end: - strbuf_release(&path); return (r->mtime != 0); } diff --git a/ui-shared.c b/ui-shared.c index 519eef7..b93b77a 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -62,7 +62,7 @@ const char *cgit_hosturl() return NULL; if (!ctx.env.server_port || atoi(ctx.env.server_port) == 80) return ctx.env.server_name; - return fmtalloc("%s:%s", ctx.env.server_name, ctx.env.server_port); + return xstrdup(fmt("%s:%s", ctx.env.server_name, ctx.env.server_port)); } const char *cgit_rooturl() @@ -75,30 +75,31 @@ const char *cgit_rooturl() char *cgit_repourl(const char *reponame) { - if (ctx.cfg.virtual_root) - return fmtalloc("%s%s/", ctx.cfg.virtual_root, reponame); - else - return fmtalloc("?r=%s", reponame); + if (ctx.cfg.virtual_root) { + return fmt("%s%s/", ctx.cfg.virtual_root, reponame); + } else { + return fmt("?r=%s", reponame); + } } char *cgit_fileurl(const char *reponame, const char *pagename, const char *filename, const char *query) { - struct strbuf sb = STRBUF_INIT; + char *tmp; char *delim; if (ctx.cfg.virtual_root) { - strbuf_addf(&sb, "%s%s/%s/%s", ctx.cfg.virtual_root, reponame, - pagename, (filename ? filename:"")); + tmp = fmt("%s%s/%s/%s", ctx.cfg.virtual_root, reponame, + pagename, (filename ? filename:"")); delim = "?"; } else { - strbuf_addf(&sb, "?url=%s/%s/%s", reponame, pagename, - (filename ? filename : "")); + tmp = fmt("?url=%s/%s/%s", reponame, pagename, + (filename ? filename : "")); delim = "&"; } if (query) - strbuf_addf(&sb, "%s%s", delim, query); - return strbuf_detach(&sb, NULL); + tmp = fmt("%s%s%s", tmp, delim, query); + return tmp; } char *cgit_pageurl(const char *reponame, const char *pagename, @@ -547,21 +548,21 @@ void cgit_submodule_link(const char *class, char *path, const char *rev) htmlf("class='%s' ", class); html("href='"); if (item) { - html_attrf(item->util, rev); + html_attr(fmt(item->util, rev)); } else if (ctx.repo->module_link) { dir = strrchr(path, '/'); if (dir) dir++; else dir = path; - html_attrf(ctx.repo->module_link, dir, rev); + html_attr(fmt(ctx.repo->module_link, dir, rev)); } else { html("#"); } html("'>"); html_txt(path); html("</a>"); - html_txtf(" @ %.7s", rev); + html_txt(fmt(" @ %.7s", rev)); if (item && tail) path[len - 1] = tail; } @@ -677,16 +678,12 @@ void cgit_print_docstart(struct cgit_context *ctx) html("'/>\n"); } if (host && ctx->repo && ctx->qry.head) { - struct strbuf sb = STRBUF_INIT; - strbuf_addf(&sb, "h=%s", ctx->qry.head); - html("<link rel='alternate' title='Atom feed' href='"); html(cgit_httpscheme()); html_attr(cgit_hosturl()); html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.vpath, - sb.buf)); + fmt("h=%s", ctx->qry.head))); html("' type='application/atom+xml'/>\n"); - strbuf_release(&sb); } if (ctx->cfg.head_include) html_include(ctx->cfg.head_include); @@ -728,14 +725,13 @@ static int print_branch_option(const char *refname, const unsigned char *sha1, void cgit_add_hidden_formfields(int incl_head, int incl_search, const char *page) { - if (!ctx.cfg.virtual_root) { - struct strbuf url = STRBUF_INIT; + char *url; - strbuf_addf(&url, "%s/%s", ctx.qry.repo, page); + if (!ctx.cfg.virtual_root) { + url = fmt("%s/%s", ctx.qry.repo, page); if (ctx.qry.vpath) - strbuf_addf(&url, "/%s", ctx.qry.vpath); - html_hidden("url", url.buf); - strbuf_release(&url); + url = fmt("%s/%s", url, ctx.qry.vpath); + html_hidden("url", url); } if (incl_head && ctx.qry.head && ctx.repo->defbranch && @@ -930,23 +926,20 @@ void cgit_print_snapshot_links(const char *repo, const char *head, const char *hex, int snapshots) { const struct cgit_snapshot_format* f; - struct strbuf filename = STRBUF_INIT; - size_t prefixlen; + char *prefix; + char *filename; unsigned char sha1[20]; if (get_sha1(fmt("refs/tags/%s", hex), sha1) == 0 && (hex[0] == 'v' || hex[0] == 'V') && isdigit(hex[1])) hex++; - strbuf_addf(&filename, "%s-%s", cgit_repobasename(repo), hex); - prefixlen = filename.len; + prefix = xstrdup(fmt("%s-%s", cgit_repobasename(repo), hex)); for (f = cgit_snapshot_formats; f->suffix; f++) { if (!(snapshots & f->bit)) continue; - strbuf_setlen(&filename, prefixlen); - strbuf_addstr(&filename, f->suffix); - cgit_snapshot_link(filename.buf, NULL, NULL, NULL, NULL, - filename.buf); + filename = fmt("%s%s", prefix, f->suffix); + cgit_snapshot_link(filename, NULL, NULL, NULL, NULL, filename); html("<br/>"); } - strbuf_release(&filename); + free(prefix); } diff --git a/ui-snapshot.c b/ui-snapshot.c index 8e76977..a47884e 100644 --- a/ui-snapshot.c +++ b/ui-snapshot.c @@ -15,33 +15,14 @@ static int write_archive_type(const char *format, const char *hex, const char *prefix) { struct argv_array argv = ARGV_ARRAY_INIT; - const char **nargv; - int result; argv_array_push(&argv, "snapshot"); argv_array_push(&argv, format); if (prefix) { - struct strbuf buf = STRBUF_INIT; - strbuf_addstr(&buf, prefix); - strbuf_addch(&buf, '/'); argv_array_push(&argv, "--prefix"); - argv_array_push(&argv, buf.buf); - strbuf_release(&buf); + argv_array_push(&argv, fmt("%s/", prefix)); } argv_array_push(&argv, hex); - /* - * Now we need to copy the pointers to arguments into a new - * structure because write_archive will rearrange its arguments - * which may result in duplicated/missing entries causing leaks - * or double-frees in argv_array_clear. - */ - nargv = xmalloc(sizeof(char *) * (argv.argc + 1)); - /* argv_array guarantees a trailing NULL entry. */ - memcpy(nargv, argv.argv, sizeof(char *) * (argv.argc + 1)); - - result = write_archive(argv.argc, nargv, NULL, 1, NULL, 0); - argv_array_clear(&argv); - free(nargv); - return result; + return write_archive(argv.argc, argv.argv, NULL, 1, NULL, 0); } static int write_tar_archive(const char *hex, const char *prefix) @@ -148,36 +129,29 @@ static const char *get_ref_from_filename(const char *url, const char *filename, { const char *reponame; unsigned char sha1[20]; - struct strbuf snapshot = STRBUF_INIT; - int result = 1; + char *snapshot; - strbuf_addstr(&snapshot, filename); - strbuf_setlen(&snapshot, snapshot.len - strlen(format->suffix)); + snapshot = xstrdup(filename); + snapshot[strlen(snapshot) - strlen(format->suffix)] = '\0'; - if (get_sha1(snapshot.buf, sha1) == 0) - goto out; + if (get_sha1(snapshot, sha1) == 0) + return snapshot; reponame = cgit_repobasename(url); - if (prefixcmp(snapshot.buf, reponame) == 0) { - const char *new_start = snapshot.buf; - new_start += strlen(reponame); - while (new_start && (*new_start == '-' || *new_start == '_')) - new_start++; - strbuf_splice(&snapshot, 0, new_start - snapshot.buf, "", 0); + if (prefixcmp(snapshot, reponame) == 0) { + snapshot += strlen(reponame); + while (snapshot && (*snapshot == '-' || *snapshot == '_')) + snapshot++; } - if (get_sha1(snapshot.buf, sha1) == 0) - goto out; - - strbuf_insert(&snapshot, 0, "v", 1); - if (get_sha1(snapshot.buf, sha1) == 0) - goto out; + if (get_sha1(snapshot, sha1) == 0) + return snapshot; - result = 0; - strbuf_release(&snapshot); + snapshot = fmt("v%s", snapshot); + if (get_sha1(snapshot, sha1) == 0) + return snapshot; -out: - return result ? strbuf_detach(&snapshot, NULL) : NULL; + return NULL; } __attribute__((format (printf, 1, 2))) diff --git a/ui-summary.c b/ui-summary.c index f965b32..bd123ef 100644 --- a/ui-summary.c +++ b/ui-summary.c @@ -17,7 +17,6 @@ static void print_url(char *base, char *suffix) { int columns = 3; - struct strbuf basebuf = STRBUF_INIT; if (ctx.repo->enable_log_filecount) columns++; @@ -26,16 +25,13 @@ static void print_url(char *base, char *suffix) if (!base || !*base) return; - if (suffix && *suffix) { - strbuf_addf(&basebuf, "%s/%s", base, suffix); - base = basebuf.buf; - } + if (suffix && *suffix) + base = fmt("%s/%s", base, suffix); htmlf("<tr><td colspan='%d'><a href='", columns); html_url_path(base); html("'>"); html_txt(base); html("</a></td></tr>\n"); - strbuf_release(&basebuf); } static void print_urls(char *txt, char *suffix) @@ -116,8 +112,8 @@ void cgit_print_repo_readme(char *path) /* Prepend repo path to relative readme path unless tracked. */ if (!ref && *ctx.repo->readme != '/') - ctx.repo->readme = fmtalloc("%s/%s", ctx.repo->path, - ctx.repo->readme); + ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, + ctx.repo->readme)); /* If a subpath is specified for the about page, make it relative * to the directory containing the configured readme. @@ -41,7 +41,6 @@ static void print_download_links(char *revname) void cgit_print_tag(char *revname) { - struct strbuf fullref = STRBUF_INIT; unsigned char sha1[20]; struct object *obj; struct tag *tag; @@ -50,21 +49,20 @@ void cgit_print_tag(char *revname) if (!revname) revname = ctx.qry.head; - strbuf_addf(&fullref, "refs/tags/%s", revname); - if (get_sha1(fullref.buf, sha1)) { + if (get_sha1(fmt("refs/tags/%s", revname), sha1)) { cgit_print_error("Bad tag reference: %s", revname); - goto cleanup; + return; } obj = parse_object(sha1); if (!obj) { cgit_print_error("Bad object id: %s", sha1_to_hex(sha1)); - goto cleanup; + return; } if (obj->type == OBJ_TAG) { tag = lookup_tag(sha1); if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) { cgit_print_error("Bad tag object: %s", revname); - goto cleanup; + return; } html("<table class='commit-info'>\n"); htmlf("<tr><td>tag name</td><td>"); @@ -103,7 +101,5 @@ void cgit_print_tag(char *revname) print_download_links(revname); html("</table>\n"); } - -cleanup: - strbuf_release(&fullref); + return; } @@ -129,14 +129,14 @@ static int ls_item(const unsigned char *sha1, const char *base, int baselen, { struct walk_tree_context *walk_tree_ctx = cbdata; char *name; - struct strbuf fullpath = STRBUF_INIT; - struct strbuf class = STRBUF_INIT; + char *fullpath; + char *class; enum object_type type; unsigned long size = 0; name = xstrdup(pathname); - strbuf_addf(&fullpath, "%s%s%s", ctx.qry.path ? ctx.qry.path : "", - ctx.qry.path ? "/" : "", name); + fullpath = fmt("%s%s%s", ctx.qry.path ? ctx.qry.path : "", + ctx.qry.path ? "/" : "", name); if (!S_ISGITLINK(mode)) { type = sha1_object_info(sha1, &size); @@ -152,34 +152,33 @@ static int ls_item(const unsigned char *sha1, const char *base, int baselen, cgit_print_filemode(mode); html("</td><td>"); if (S_ISGITLINK(mode)) { - cgit_submodule_link("ls-mod", fullpath.buf, sha1_to_hex(sha1)); + cgit_submodule_link("ls-mod", fullpath, sha1_to_hex(sha1)); } else if (S_ISDIR(mode)) { cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, - walk_tree_ctx->curr_rev, fullpath.buf); + walk_tree_ctx->curr_rev, fullpath); } else { - char *ext = strrchr(name, '.'); - strbuf_addstr(&class, "ls-blob"); - if (ext) - strbuf_addf(&class, " %s", ext + 1); - cgit_tree_link(name, NULL, class.buf, ctx.qry.head, - walk_tree_ctx->curr_rev, fullpath.buf); + class = strrchr(name, '.'); + if (class != NULL) { + class = fmt("ls-blob %s", class + 1); + } else + class = "ls-blob"; + cgit_tree_link(name, NULL, class, ctx.qry.head, + walk_tree_ctx->curr_rev, fullpath); } htmlf("</td><td class='ls-size'>%li</td>", size); html("<td>"); cgit_log_link("log", NULL, "button", ctx.qry.head, - walk_tree_ctx->curr_rev, fullpath.buf, 0, NULL, NULL, + walk_tree_ctx->curr_rev, fullpath, 0, NULL, NULL, ctx.qry.showmsg); if (ctx.repo->max_stats) cgit_stats_link("stats", NULL, "button", ctx.qry.head, - fullpath.buf); + fullpath); if (!S_ISGITLINK(mode)) cgit_plain_link("plain", NULL, "button", ctx.qry.head, - walk_tree_ctx->curr_rev, fullpath.buf); + walk_tree_ctx->curr_rev, fullpath); html("</td></tr>\n"); free(name); - strbuf_release(&fullpath); - strbuf_release(&class); return 0; } |