-rw-r--r-- | cache.c | 10 | ||||
-rw-r--r-- | cgit.c | 33 | ||||
-rw-r--r-- | cgit.h | 72 | ||||
-rw-r--r-- | shared.c | 138 | ||||
-rw-r--r-- | ui-repolist.c | 18 | ||||
-rw-r--r-- | ui-shared.c | 60 | ||||
-rw-r--r-- | ui-summary.c | 10 |
7 files changed, 166 insertions, 175 deletions
@@ -1,119 +1,119 @@ /* cache.c: cache management * * Copyright (C) 2006 Lars Hjemli * * Licensed under GNU General Public License v2 * (see COPYING for full license text) */ #include "cgit.h" const int NOLOCK = -1; char *cache_safe_filename(const char *unsafe) { static char buf[4][PATH_MAX]; static int bufidx; char *s; char c; bufidx++; bufidx &= 3; s = buf[bufidx]; while(unsafe && (c = *unsafe++) != 0) { if (c == '/' || c == ' ' || c == '&' || c == '|' || c == '>' || c == '<' || c == '.') c = '_'; *s++ = c; } *s = '\0'; return buf[bufidx]; } int cache_exist(struct cacheitem *item) { if (stat(item->name, &item->st)) { item->st.st_mtime = 0; return 0; } return 1; } int cache_create_dirs() { char *path; - path = fmt("%s", cgit_cache_root); + path = fmt("%s", ctx.cfg.cache_root); if (mkdir(path, S_IRWXU) && errno!=EEXIST) return 0; if (!cgit_repo) return 0; - path = fmt("%s/%s", cgit_cache_root, + path = fmt("%s/%s", ctx.cfg.cache_root, cache_safe_filename(cgit_repo->url)); if (mkdir(path, S_IRWXU) && errno!=EEXIST) return 0; if (ctx.qry.page) { - path = fmt("%s/%s/%s", cgit_cache_root, + path = fmt("%s/%s/%s", ctx.cfg.cache_root, cache_safe_filename(cgit_repo->url), ctx.qry.page); if (mkdir(path, S_IRWXU) && errno!=EEXIST) return 0; } return 1; } int cache_refill_overdue(const char *lockfile) { struct stat st; if (stat(lockfile, &st)) return 0; else - return (time(NULL) - st.st_mtime > cgit_cache_max_create_time); + return (time(NULL) - st.st_mtime > ctx.cfg.cache_max_create_time); } int cache_lock(struct cacheitem *item) { int i = 0; char *lockfile = xstrdup(fmt("%s.lock", item->name)); top: - if (++i > cgit_max_lock_attempts) + if (++i > ctx.cfg.max_lock_attempts) die("cache_lock: unable to lock %s: %s", item->name, strerror(errno)); item->fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR); if (item->fd == NOLOCK && errno == ENOENT && cache_create_dirs()) goto top; if (item->fd == NOLOCK && errno == EEXIST && cache_refill_overdue(lockfile) && !unlink(lockfile)) goto top; free(lockfile); return (item->fd > 0); } int cache_unlock(struct cacheitem *item) { close(item->fd); return (rename(fmt("%s.lock", item->name), item->name) == 0); } int cache_cancel_lock(struct cacheitem *item) { return (unlink(fmt("%s.lock", item->name)) == 0); } int cache_expired(struct cacheitem *item) { if (item->ttl < 0) return 0; return item->st.st_mtime + item->ttl * 60 < time(NULL); } @@ -1,318 +1,319 @@ /* cgit.c: cgi for the git scm * * Copyright (C) 2006 Lars Hjemli * * Licensed under GNU General Public License v2 * (see COPYING for full license text) */ #include "cgit.h" static int cgit_prepare_cache(struct cacheitem *item) { if (!cgit_repo && ctx.qry.repo) { - char *title = fmt("%s - %s", cgit_root_title, "Bad request"); + char *title = fmt("%s - %s", ctx.cfg.root_title, "Bad request"); cgit_print_docstart(title, item); cgit_print_pageheader(title, 0); cgit_print_error(fmt("Unknown repo: %s", ctx.qry.repo)); cgit_print_docend(); return 0; } if (!cgit_repo) { - item->name = xstrdup(fmt("%s/index.html", cgit_cache_root)); - item->ttl = cgit_cache_root_ttl; + item->name = xstrdup(fmt("%s/index.html", ctx.cfg.cache_root)); + item->ttl = ctx.cfg.cache_root_ttl; return 1; } if (!cgit_cmd) { - item->name = xstrdup(fmt("%s/%s/index.%s.html", cgit_cache_root, + item->name = xstrdup(fmt("%s/%s/index.%s.html", ctx.cfg.cache_root, cache_safe_filename(cgit_repo->url), cache_safe_filename(ctx.qry.raw))); - item->ttl = cgit_cache_repo_ttl; + item->ttl = ctx.cfg.cache_repo_ttl; } else { - item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root, + item->name = xstrdup(fmt("%s/%s/%s/%s.html", ctx.cfg.cache_root, cache_safe_filename(cgit_repo->url), ctx.qry.page, cache_safe_filename(ctx.qry.raw))); if (ctx.qry.has_symref) - item->ttl = cgit_cache_dynamic_ttl; + item->ttl = ctx.cfg.cache_dynamic_ttl; else if (ctx.qry.has_sha1) - item->ttl = cgit_cache_static_ttl; + item->ttl = ctx.cfg.cache_static_ttl; else - item->ttl = cgit_cache_repo_ttl; + item->ttl = ctx.cfg.cache_repo_ttl; } return 1; } struct refmatch { char *req_ref; char *first_ref; int match; }; int find_current_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data) { struct refmatch *info; info = (struct refmatch *)cb_data; if (!strcmp(refname, info->req_ref)) info->match = 1; if (!info->first_ref) info->first_ref = xstrdup(refname); return info->match; } char *find_default_branch(struct repoinfo *repo) { struct refmatch info; info.req_ref = repo->defbranch; info.first_ref = NULL; info.match = 0; for_each_branch_ref(find_current_ref, &info); if (info.match) return info.req_ref; else return info.first_ref; } static void cgit_print_repo_page(struct cacheitem *item) { char *title, *tmp; int show_search; unsigned char sha1[20]; if (chdir(cgit_repo->path)) { - title = fmt("%s - %s", cgit_root_title, "Bad request"); + title = fmt("%s - %s", ctx.cfg.root_title, "Bad request"); cgit_print_docstart(title, item); cgit_print_pageheader(title, 0); cgit_print_error(fmt("Unable to scan repository: %s", strerror(errno))); cgit_print_docend(); return; } title = fmt("%s - %s", cgit_repo->name, cgit_repo->desc); show_search = 0; setenv("GIT_DIR", cgit_repo->path, 1); if (!ctx.qry.head) { ctx.qry.head = xstrdup(find_default_branch(cgit_repo)); cgit_repo->defbranch = ctx.qry.head; } if (!ctx.qry.head) { cgit_print_docstart(title, item); cgit_print_pageheader(title, 0); cgit_print_error("Repository seems to be empty"); cgit_print_docend(); return; } if (get_sha1(ctx.qry.head, sha1)) { tmp = xstrdup(ctx.qry.head); ctx.qry.head = cgit_repo->defbranch; cgit_print_docstart(title, item); cgit_print_pageheader(title, 0); cgit_print_error(fmt("Invalid branch: %s", tmp)); cgit_print_docend(); return; } if ((cgit_cmd == CMD_SNAPSHOT) && cgit_repo->snapshots) { cgit_print_snapshot(item, ctx.qry.head, ctx.qry.sha1, cgit_repobasename(cgit_repo->url), ctx.qry.path, cgit_repo->snapshots ); return; } if (cgit_cmd == CMD_PATCH) { cgit_print_patch(ctx.qry.sha1, item); return; } if (cgit_cmd == CMD_BLOB) { cgit_print_blob(item, ctx.qry.sha1, ctx.qry.path); return; } show_search = (cgit_cmd == CMD_LOG); cgit_print_docstart(title, item); if (!cgit_cmd) { cgit_print_pageheader("summary", show_search); cgit_print_summary(); cgit_print_docend(); return; } cgit_print_pageheader(ctx.qry.page, show_search); switch(cgit_cmd) { case CMD_LOG: cgit_print_log(ctx.qry.sha1, ctx.qry.ofs, - cgit_max_commit_count, ctx.qry.grep, ctx.qry.search, + ctx.cfg.max_commit_count, ctx.qry.grep, ctx.qry.search, ctx.qry.path, 1); break; case CMD_TREE: cgit_print_tree(ctx.qry.sha1, ctx.qry.path); break; case CMD_COMMIT: cgit_print_commit(ctx.qry.sha1); break; case CMD_REFS: cgit_print_refs(); break; case CMD_TAG: cgit_print_tag(ctx.qry.sha1); break; case CMD_DIFF: cgit_print_diff(ctx.qry.sha1, ctx.qry.sha2, ctx.qry.path); break; default: cgit_print_error("Invalid request"); } cgit_print_docend(); } static void cgit_fill_cache(struct cacheitem *item, int use_cache) { static char buf[PATH_MAX]; int stdout2; getcwd(buf, sizeof(buf)); item->st.st_mtime = time(NULL); if (use_cache) { stdout2 = chk_positive(dup(STDOUT_FILENO), "Preserving STDOUT"); chk_zero(close(STDOUT_FILENO), "Closing STDOUT"); chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)"); } if (cgit_repo) cgit_print_repo_page(item); else cgit_print_repolist(item); if (use_cache) { chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT"); chk_positive(dup2(stdout2, STDOUT_FILENO), "Restoring original STDOUT"); chk_zero(close(stdout2), "Closing temporary STDOUT"); } chdir(buf); } static void cgit_check_cache(struct cacheitem *item) { int i = 0; top: - if (++i > cgit_max_lock_attempts) { + if (++i > ctx.cfg.max_lock_attempts) { die("cgit_refresh_cache: unable to lock %s: %s", item->name, strerror(errno)); } if (!cache_exist(item)) { if (!cache_lock(item)) { sleep(1); goto top; } if (!cache_exist(item)) { cgit_fill_cache(item, 1); cache_unlock(item); } else { cache_cancel_lock(item); } } else if (cache_expired(item) && cache_lock(item)) { if (cache_expired(item)) { cgit_fill_cache(item, 1); cache_unlock(item); } else { cache_cancel_lock(item); } } } static void cgit_print_cache(struct cacheitem *item) { static char buf[4096]; ssize_t i; int fd = open(item->name, O_RDONLY); if (fd<0) die("Unable to open cached file %s", item->name); while((i=read(fd, buf, sizeof(buf))) > 0) write(STDOUT_FILENO, buf, i); close(fd); } static void cgit_parse_args(int argc, const char **argv) { int i; for (i = 1; i < argc; i++) { if (!strncmp(argv[i], "--cache=", 8)) { - cgit_cache_root = xstrdup(argv[i]+8); + ctx.cfg.cache_root = xstrdup(argv[i]+8); } if (!strcmp(argv[i], "--nocache")) { - cgit_nocache = 1; + ctx.cfg.nocache = 1; } if (!strncmp(argv[i], "--query=", 8)) { ctx.qry.raw = xstrdup(argv[i]+8); } if (!strncmp(argv[i], "--repo=", 7)) { ctx.qry.repo = xstrdup(argv[i]+7); } if (!strncmp(argv[i], "--page=", 7)) { ctx.qry.page = xstrdup(argv[i]+7); } if (!strncmp(argv[i], "--head=", 7)) { ctx.qry.head = xstrdup(argv[i]+7); ctx.qry.has_symref = 1; } if (!strncmp(argv[i], "--sha1=", 7)) { ctx.qry.sha1 = xstrdup(argv[i]+7); ctx.qry.has_sha1 = 1; } if (!strncmp(argv[i], "--ofs=", 6)) { ctx.qry.ofs = atoi(argv[i]+6); } } } int main(int argc, const char **argv) { struct cacheitem item; const char *cgit_config_env = getenv("CGIT_CONFIG"); + cgit_prepare_context(&ctx); htmlfd = STDOUT_FILENO; item.st.st_mtime = time(NULL); cgit_repolist.length = 0; cgit_repolist.count = 0; cgit_repolist.repos = NULL; cgit_read_config(cgit_config_env ? cgit_config_env : CGIT_CONFIG, cgit_global_config_cb); cgit_repo = NULL; if (getenv("SCRIPT_NAME")) - cgit_script_name = xstrdup(getenv("SCRIPT_NAME")); + ctx.cfg.script_name = xstrdup(getenv("SCRIPT_NAME")); if (getenv("QUERY_STRING")) ctx.qry.raw = xstrdup(getenv("QUERY_STRING")); cgit_parse_args(argc, argv); cgit_parse_query(ctx.qry.raw, cgit_querystring_cb); if (!cgit_prepare_cache(&item)) return 0; - if (cgit_nocache) { + if (ctx.cfg.nocache) { cgit_fill_cache(&item, 0); } else { cgit_check_cache(&item); cgit_print_cache(&item); } return 0; } @@ -94,144 +94,146 @@ struct commitinfo { char *author_email; unsigned long author_date; char *committer; char *committer_email; unsigned long committer_date; char *subject; char *msg; char *msg_encoding; }; struct taginfo { char *tagger; char *tagger_email; int tagger_date; char *msg; }; struct refinfo { const char *refname; struct object *object; union { struct taginfo *tag; struct commitinfo *commit; }; }; struct reflist { struct refinfo **refs; int alloc; int count; }; struct cgit_query { int has_symref; int has_sha1; char *raw; char *repo; char *page; char *search; char *grep; char *head; char *sha1; char *sha2; char *path; char *name; int ofs; }; +struct cgit_config { + char *agefile; + char *cache_root; + char *clone_prefix; + char *css; + char *index_header; + char *index_info; + char *logo; + char *logo_link; + char *module_link; + char *repo_group; + char *robots; + char *root_title; + char *script_name; + char *virtual_root; + int cache_dynamic_ttl; + int cache_max_create_time; + int cache_repo_ttl; + int cache_root_ttl; + int cache_static_ttl; + int enable_index_links; + int enable_log_filecount; + int enable_log_linecount; + int max_commit_count; + int max_lock_attempts; + int max_msg_len; + int max_repodesc_len; + int nocache; + int renamelimit; + int snapshots; + int summary_branches; + int summary_log; + int summary_tags; +}; + struct cgit_context { struct cgit_query qry; + struct cgit_config cfg; }; extern const char *cgit_version; extern struct repolist cgit_repolist; extern struct repoinfo *cgit_repo; extern struct cgit_context ctx; extern int cgit_cmd; -extern char *cgit_root_title; -extern char *cgit_css; -extern char *cgit_logo; -extern char *cgit_index_header; -extern char *cgit_index_info; -extern char *cgit_logo_link; -extern char *cgit_module_link; -extern char *cgit_agefile; -extern char *cgit_virtual_root; -extern char *cgit_script_name; -extern char *cgit_cache_root; -extern char *cgit_repo_group; -extern char *cgit_robots; -extern char *cgit_clone_prefix; - -extern int cgit_nocache; -extern int cgit_snapshots; -extern int cgit_enable_index_links; -extern int cgit_enable_log_filecount; -extern int cgit_enable_log_linecount; -extern int cgit_max_lock_attempts; -extern int cgit_cache_root_ttl; -extern int cgit_cache_repo_ttl; -extern int cgit_cache_dynamic_ttl; -extern int cgit_cache_static_ttl; -extern int cgit_cache_max_create_time; -extern int cgit_summary_log; -extern int cgit_summary_tags; -extern int cgit_summary_branches; - -extern int cgit_max_msg_len; -extern int cgit_max_repodesc_len; -extern int cgit_max_commit_count; - - extern int htmlfd; +extern void cgit_prepare_context(struct cgit_context *ctx); extern int cgit_get_cmd_index(const char *cmd); extern struct repoinfo *cgit_get_repoinfo(const char *url); extern void cgit_global_config_cb(const char *name, const char *value); extern void cgit_repo_config_cb(const char *name, const char *value); extern void cgit_querystring_cb(const char *name, const char *value); extern int chk_zero(int result, char *msg); extern int chk_positive(int result, char *msg); extern int chk_non_negative(int result, char *msg); extern int hextoint(char c); extern char *trim_end(const char *str, char c); extern char *strlpart(char *txt, int maxlen); extern char *strrpart(char *txt, int maxlen); extern void cgit_add_ref(struct reflist *list, struct refinfo *ref); extern int cgit_refs_cb(const char *refname, const unsigned char *sha1, int flags, void *cb_data); extern void *cgit_free_commitinfo(struct commitinfo *info); extern int cgit_diff_files(const unsigned char *old_sha1, const unsigned char *new_sha1, linediff_fn fn); extern void cgit_diff_tree(const unsigned char *old_sha1, const unsigned char *new_sha1, filepair_fn fn, const char *prefix); extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); extern char *fmt(const char *format,...); extern void html(const char *txt); extern void htmlf(const char *format,...); extern void html_txt(char *txt); extern void html_ntxt(int len, char *txt); extern void html_attr(char *txt); extern void html_hidden(char *name, char *value); extern void html_option(char *value, char *text, char *selected_value); extern void html_link_open(char *url, char *title, char *class); extern void html_link_close(void); extern void html_filemode(unsigned short mode); extern int html_include(const char *filename); extern int cgit_read_config(const char *filename, configfn fn); extern int cgit_parse_query(char *txt, configfn fn); extern struct commitinfo *cgit_parse_commit(struct commit *commit); @@ -1,260 +1,248 @@ /* shared.c: global vars + some callback functions * * Copyright (C) 2006 Lars Hjemli * * Licensed under GNU General Public License v2 * (see COPYING for full license text) */ #include "cgit.h" struct repolist cgit_repolist; struct repoinfo *cgit_repo; struct cgit_context ctx; int cgit_cmd; const char *cgit_version = CGIT_VERSION; -char *cgit_root_title = "Git repository browser"; -char *cgit_css = "/cgit.css"; -char *cgit_logo = "/git-logo.png"; -char *cgit_index_header = NULL; -char *cgit_index_info = NULL; -char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/"; -char *cgit_module_link = "./?repo=%s&page=commit&id=%s"; -char *cgit_agefile = "info/web/last-modified"; -char *cgit_virtual_root = NULL; -char *cgit_script_name = CGIT_SCRIPT_NAME; -char *cgit_cache_root = CGIT_CACHE_ROOT; -char *cgit_repo_group = NULL; -char *cgit_robots = "index, nofollow"; -char *cgit_clone_prefix = NULL; - -int cgit_nocache = 0; -int cgit_snapshots = 0; -int cgit_enable_index_links = 0; -int cgit_enable_log_filecount = 0; -int cgit_enable_log_linecount = 0; -int cgit_max_lock_attempts = 5; -int cgit_cache_root_ttl = 5; -int cgit_cache_repo_ttl = 5; -int cgit_cache_dynamic_ttl = 5; -int cgit_cache_static_ttl = -1; -int cgit_cache_max_create_time = 5; -int cgit_summary_log = 0; -int cgit_summary_tags = 0; -int cgit_summary_branches = 0; -int cgit_renamelimit = -1; - -int cgit_max_msg_len = 60; -int cgit_max_repodesc_len = 60; -int cgit_max_commit_count = 50; - int htmlfd = 0; +void cgit_prepare_context(struct cgit_context *ctx) +{ + memset(ctx, 0, sizeof(ctx)); + ctx->cfg.agefile = "info/web/last-modified"; + ctx->cfg.cache_dynamic_ttl = 5; + ctx->cfg.cache_max_create_time = 5; + ctx->cfg.cache_repo_ttl = 5; + ctx->cfg.cache_root = CGIT_CACHE_ROOT; + ctx->cfg.cache_root_ttl = 5; + ctx->cfg.cache_static_ttl = -1; + ctx->cfg.css = "/cgit.css"; + ctx->cfg.logo = "/git-logo.png"; + ctx->cfg.max_commit_count = 50; + ctx->cfg.max_lock_attempts = 5; + ctx->cfg.max_msg_len = 60; + ctx->cfg.max_repodesc_len = 60; + ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; + ctx->cfg.renamelimit = -1; + ctx->cfg.robots = "index, nofollow"; + ctx->cfg.root_title = "Git repository browser"; + ctx->cfg.script_name = CGIT_SCRIPT_NAME; +} + int cgit_get_cmd_index(const char *cmd) { static char *cmds[] = {"log", "commit", "diff", "tree", "blob", "snapshot", "tag", "refs", "patch", NULL}; int i; for(i = 0; cmds[i]; i++) if (!strcmp(cmd, cmds[i])) return i + 1; return 0; } int chk_zero(int result, char *msg) { if (result != 0) die("%s: %s", msg, strerror(errno)); return result; } int chk_positive(int result, char *msg) { if (result <= 0) die("%s: %s", msg, strerror(errno)); return result; } int chk_non_negative(int result, char *msg) { if (result < 0) die("%s: %s",msg, strerror(errno)); return result; } struct repoinfo *add_repo(const char *url) { struct repoinfo *ret; if (++cgit_repolist.count > cgit_repolist.length) { if (cgit_repolist.length == 0) cgit_repolist.length = 8; else cgit_repolist.length *= 2; cgit_repolist.repos = xrealloc(cgit_repolist.repos, cgit_repolist.length * sizeof(struct repoinfo)); } ret = &cgit_repolist.repos[cgit_repolist.count-1]; ret->url = trim_end(url, '/'); ret->name = ret->url; ret->path = NULL; ret->desc = "[no description]"; ret->owner = NULL; - ret->group = cgit_repo_group; + ret->group = ctx.cfg.repo_group; ret->defbranch = "master"; - ret->snapshots = cgit_snapshots; - ret->enable_log_filecount = cgit_enable_log_filecount; - ret->enable_log_linecount = cgit_enable_log_linecount; - ret->module_link = cgit_module_link; + ret->snapshots = ctx.cfg.snapshots; + ret->enable_log_filecount = ctx.cfg.enable_log_filecount; + ret->enable_log_linecount = ctx.cfg.enable_log_linecount; + ret->module_link = ctx.cfg.module_link; ret->readme = NULL; return ret; } struct repoinfo *cgit_get_repoinfo(const char *url) { int i; struct repoinfo *repo; for (i=0; i<cgit_repolist.count; i++) { repo = &cgit_repolist.repos[i]; if (!strcmp(repo->url, url)) return repo; } return NULL; } void cgit_global_config_cb(const char *name, const char *value) { if (!strcmp(name, "root-title")) - cgit_root_title = xstrdup(value); + ctx.cfg.root_title = xstrdup(value); else if (!strcmp(name, "css")) - cgit_css = xstrdup(value); + ctx.cfg.css = xstrdup(value); else if (!strcmp(name, "logo")) - cgit_logo = xstrdup(value); + ctx.cfg.logo = xstrdup(value); else if (!strcmp(name, "index-header")) - cgit_index_header = xstrdup(value); + ctx.cfg.index_header = xstrdup(value); else if (!strcmp(name, "index-info")) - cgit_index_info = xstrdup(value); + ctx.cfg.index_info = xstrdup(value); else if (!strcmp(name, "logo-link")) - cgit_logo_link = xstrdup(value); + ctx.cfg.logo_link = xstrdup(value); else if (!strcmp(name, "module-link")) - cgit_module_link = xstrdup(value); + ctx.cfg.module_link = xstrdup(value); else if (!strcmp(name, "virtual-root")) { - cgit_virtual_root = trim_end(value, '/'); - if (!cgit_virtual_root && (!strcmp(value, "/"))) - cgit_virtual_root = ""; + ctx.cfg.virtual_root = trim_end(value, '/'); + if (!ctx.cfg.virtual_root && (!strcmp(value, "/"))) + ctx.cfg.virtual_root = ""; } else if (!strcmp(name, "nocache")) - cgit_nocache = atoi(value); + ctx.cfg.nocache = atoi(value); else if (!strcmp(name, "snapshots")) - cgit_snapshots = cgit_parse_snapshots_mask(value); + ctx.cfg.snapshots = cgit_parse_snapshots_mask(value); else if (!strcmp(name, "enable-index-links")) - cgit_enable_index_links = atoi(value); + ctx.cfg.enable_index_links = atoi(value); else if (!strcmp(name, "enable-log-filecount")) - cgit_enable_log_filecount = atoi(value); + ctx.cfg.enable_log_filecount = atoi(value); else if (!strcmp(name, "enable-log-linecount")) - cgit_enable_log_linecount = atoi(value); + ctx.cfg.enable_log_linecount = atoi(value); else if (!strcmp(name, "cache-root")) - cgit_cache_root = xstrdup(value); + ctx.cfg.cache_root = xstrdup(value); else if (!strcmp(name, "cache-root-ttl")) - cgit_cache_root_ttl = atoi(value); + ctx.cfg.cache_root_ttl = atoi(value); else if (!strcmp(name, "cache-repo-ttl")) - cgit_cache_repo_ttl = atoi(value); + ctx.cfg.cache_repo_ttl = atoi(value); else if (!strcmp(name, "cache-static-ttl")) - cgit_cache_static_ttl = atoi(value); + ctx.cfg.cache_static_ttl = atoi(value); else if (!strcmp(name, "cache-dynamic-ttl")) - cgit_cache_dynamic_ttl = atoi(value); + ctx.cfg.cache_dynamic_ttl = atoi(value); else if (!strcmp(name, "max-message-length")) - cgit_max_msg_len = atoi(value); + ctx.cfg.max_msg_len = atoi(value); else if (!strcmp(name, "max-repodesc-length")) - cgit_max_repodesc_len = atoi(value); + ctx.cfg.max_repodesc_len = atoi(value); else if (!strcmp(name, "max-commit-count")) - cgit_max_commit_count = atoi(value); + ctx.cfg.max_commit_count = atoi(value); else if (!strcmp(name, "summary-log")) - cgit_summary_log = atoi(value); + ctx.cfg.summary_log = atoi(value); else if (!strcmp(name, "summary-branches")) - cgit_summary_branches = atoi(value); + ctx.cfg.summary_branches = atoi(value); else if (!strcmp(name, "summary-tags")) - cgit_summary_tags = atoi(value); + ctx.cfg.summary_tags = atoi(value); else if (!strcmp(name, "agefile")) - cgit_agefile = xstrdup(value); + ctx.cfg.agefile = xstrdup(value); else if (!strcmp(name, "renamelimit")) - cgit_renamelimit = atoi(value); + ctx.cfg.renamelimit = atoi(value); else if (!strcmp(name, "robots")) - cgit_robots = xstrdup(value); + ctx.cfg.robots = xstrdup(value); else if (!strcmp(name, "clone-prefix")) - cgit_clone_prefix = xstrdup(value); + ctx.cfg.clone_prefix = xstrdup(value); else if (!strcmp(name, "repo.group")) - cgit_repo_group = xstrdup(value); + ctx.cfg.repo_group = xstrdup(value); else if (!strcmp(name, "repo.url")) cgit_repo = add_repo(value); else if (!strcmp(name, "repo.name")) cgit_repo->name = xstrdup(value); else if (cgit_repo && !strcmp(name, "repo.path")) cgit_repo->path = trim_end(value, '/'); else if (cgit_repo && !strcmp(name, "repo.clone-url")) cgit_repo->clone_url = xstrdup(value); else if (cgit_repo && !strcmp(name, "repo.desc")) cgit_repo->desc = xstrdup(value); else if (cgit_repo && !strcmp(name, "repo.owner")) cgit_repo->owner = xstrdup(value); else if (cgit_repo && !strcmp(name, "repo.defbranch")) cgit_repo->defbranch = xstrdup(value); else if (cgit_repo && !strcmp(name, "repo.snapshots")) - cgit_repo->snapshots = cgit_snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */ + cgit_repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */ else if (cgit_repo && !strcmp(name, "repo.enable-log-filecount")) - cgit_repo->enable_log_filecount = cgit_enable_log_filecount * atoi(value); + cgit_repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); else if (cgit_repo && !strcmp(name, "repo.enable-log-linecount")) - cgit_repo->enable_log_linecount = cgit_enable_log_linecount * atoi(value); + cgit_repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); else if (cgit_repo && !strcmp(name, "repo.module-link")) cgit_repo->module_link= xstrdup(value); else if (cgit_repo && !strcmp(name, "repo.readme") && value != NULL) { if (*value == '/') cgit_repo->readme = xstrdup(value); else cgit_repo->readme = xstrdup(fmt("%s/%s", cgit_repo->path, value)); } else if (!strcmp(name, "include")) cgit_read_config(value, cgit_global_config_cb); } void cgit_querystring_cb(const char *name, const char *value) { if (!strcmp(name,"r")) { ctx.qry.repo = xstrdup(value); cgit_repo = cgit_get_repoinfo(value); } else if (!strcmp(name, "p")) { ctx.qry.page = xstrdup(value); cgit_cmd = cgit_get_cmd_index(value); } else if (!strcmp(name, "url")) { cgit_parse_url(value); } else if (!strcmp(name, "qt")) { ctx.qry.grep = xstrdup(value); } else if (!strcmp(name, "q")) { ctx.qry.search = xstrdup(value); } else if (!strcmp(name, "h")) { ctx.qry.head = xstrdup(value); ctx.qry.has_symref = 1; } else if (!strcmp(name, "id")) { ctx.qry.sha1 = xstrdup(value); ctx.qry.has_sha1 = 1; } else if (!strcmp(name, "id2")) { ctx.qry.sha2 = xstrdup(value); ctx.qry.has_sha1 = 1; } else if (!strcmp(name, "ofs")) { ctx.qry.ofs = atoi(value); } else if (!strcmp(name, "path")) { ctx.qry.path = trim_end(value, '/'); } else if (!strcmp(name, "name")) { ctx.qry.name = xstrdup(value); } } void *cgit_free_commitinfo(struct commitinfo *info) { free(info->author); free(info->author_email); free(info->committer); @@ -431,76 +419,76 @@ int filediff_cb(void *priv, mmbuffer_t *mb, int nbuf) memcpy(diffbuf + buflen, mb[i].ptr, mb[i].size); ((linediff_fn)priv)(diffbuf, buflen + mb[i].size); free(diffbuf); diffbuf = NULL; buflen = 0; } if (diffbuf) { ((linediff_fn)priv)(diffbuf, buflen); free(diffbuf); diffbuf = NULL; buflen = 0; } return 0; } int cgit_diff_files(const unsigned char *old_sha1, const unsigned char *new_sha1, linediff_fn fn) { mmfile_t file1, file2; xpparam_t diff_params; xdemitconf_t emit_params; xdemitcb_t emit_cb; if (!load_mmfile(&file1, old_sha1) || !load_mmfile(&file2, new_sha1)) return 1; diff_params.flags = XDF_NEED_MINIMAL; emit_params.ctxlen = 3; emit_params.flags = XDL_EMIT_FUNCNAMES; emit_params.find_func = NULL; emit_cb.outf = filediff_cb; emit_cb.priv = fn; xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb); return 0; } void cgit_diff_tree(const unsigned char *old_sha1, const unsigned char *new_sha1, filepair_fn fn, const char *prefix) { struct diff_options opt; int ret; int prefixlen; diff_setup(&opt); opt.output_format = DIFF_FORMAT_CALLBACK; opt.detect_rename = 1; - opt.rename_limit = cgit_renamelimit; + opt.rename_limit = ctx.cfg.renamelimit; DIFF_OPT_SET(&opt, RECURSIVE); opt.format_callback = cgit_diff_tree_cb; opt.format_callback_data = fn; if (prefix) { opt.nr_paths = 1; opt.paths = &prefix; prefixlen = strlen(prefix); opt.pathlens = &prefixlen; } diff_setup_done(&opt); if (old_sha1 && !is_null_sha1(old_sha1)) ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt); else ret = diff_root_tree_sha1(new_sha1, "", &opt); diffcore_std(&opt); diff_flush(&opt); } void cgit_diff_commit(struct commit *commit, filepair_fn fn) { unsigned char *old_sha1 = NULL; if (commit->parents) old_sha1 = commit->parents->item->object.sha1; cgit_diff_tree(old_sha1, commit->object.sha1, fn, NULL); } diff --git a/ui-repolist.c b/ui-repolist.c index 3e97ca9..a6cc2cc 100644 --- a/ui-repolist.c +++ b/ui-repolist.c @@ -1,110 +1,110 @@ /* ui-repolist.c: functions for generating the repolist page * * Copyright (C) 2006 Lars Hjemli * * Licensed under GNU General Public License v2 * (see COPYING for full license text) */ #include "cgit.h" #include <time.h> time_t read_agefile(char *path) { FILE *f; static char buf[64], buf2[64]; if (!(f = fopen(path, "r"))) return -1; fgets(buf, sizeof(buf), f); fclose(f); if (parse_date(buf, buf2, sizeof(buf2))) return strtoul(buf2, NULL, 10); else return 0; } static void print_modtime(struct repoinfo *repo) { char *path; struct stat s; - path = fmt("%s/%s", repo->path, cgit_agefile); + path = fmt("%s/%s", repo->path, ctx.cfg.agefile); if (stat(path, &s) == 0) { cgit_print_age(read_agefile(path), -1, NULL); return; } path = fmt("%s/refs/heads/%s", repo->path, repo->defbranch); if (stat(path, &s) != 0) return; cgit_print_age(s.st_mtime, -1, NULL); } void cgit_print_repolist(struct cacheitem *item) { int i, columns = 4; char *last_group = NULL; - if (cgit_enable_index_links) + if (ctx.cfg.enable_index_links) columns++; - cgit_print_docstart(cgit_root_title, item); - cgit_print_pageheader(cgit_root_title, 0); + cgit_print_docstart(ctx.cfg.root_title, item); + cgit_print_pageheader(ctx.cfg.root_title, 0); html("<table summary='repository list' class='list nowrap'>"); - if (cgit_index_header) { + if (ctx.cfg.index_header) { htmlf("<tr class='nohover'><td colspan='%d' class='include-block'>", columns); - html_include(cgit_index_header); + html_include(ctx.cfg.index_header); html("</td></tr>"); } html("<tr class='nohover'>" "<th class='left'>Name</th>" "<th class='left'>Description</th>" "<th class='left'>Owner</th>" "<th class='left'>Idle</th>"); - if (cgit_enable_index_links) + if (ctx.cfg.enable_index_links) html("<th>Links</th>"); html("</tr>\n"); for (i=0; i<cgit_repolist.count; i++) { cgit_repo = &cgit_repolist.repos[i]; if ((last_group == NULL && cgit_repo->group != NULL) || (last_group != NULL && cgit_repo->group == NULL) || (last_group != NULL && cgit_repo->group != NULL && strcmp(cgit_repo->group, last_group))) { htmlf("<tr class='nohover'><td colspan='%d' class='repogroup'>", columns); html_txt(cgit_repo->group); html("</td></tr>"); last_group = cgit_repo->group; } htmlf("<tr><td class='%s'>", cgit_repo->group ? "sublevel-repo" : "toplevel-repo"); html_link_open(cgit_repourl(cgit_repo->url), NULL, NULL); html_txt(cgit_repo->name); html_link_close(); html("</td><td>"); - html_ntxt(cgit_max_repodesc_len, cgit_repo->desc); + html_ntxt(ctx.cfg.max_repodesc_len, cgit_repo->desc); html("</td><td>"); html_txt(cgit_repo->owner); html("</td><td>"); print_modtime(cgit_repo); html("</td>"); - if (cgit_enable_index_links) { + if (ctx.cfg.enable_index_links) { html("<td>"); html_link_open(cgit_repourl(cgit_repo->url), NULL, "button"); html("summary</a>"); cgit_log_link("log", NULL, "button", NULL, NULL, NULL, 0, NULL, NULL); cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL); html("</td>"); } html("</tr>\n"); } html("</table>"); cgit_print_docend(); } diff --git a/ui-shared.c b/ui-shared.c index 6a41fb0..b96237d 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -1,284 +1,284 @@ /* ui-shared.c: common web output functions * * Copyright (C) 2006 Lars Hjemli * * Licensed under GNU General Public License v2 * (see COPYING for full license text) */ #include "cgit.h" const char cgit_doctype[] = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; static char *http_date(time_t t) { static char day[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; static char month[][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Now", "Dec"}; struct tm *tm = gmtime(&t); return fmt("%s, %02d %s %04d %02d:%02d:%02d GMT", day[tm->tm_wday], tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec); } static long ttl_seconds(long ttl) { if (ttl<0) return 60 * 60 * 24 * 365; else return ttl * 60; } void cgit_print_error(char *msg) { html("<div class='error'>"); html_txt(msg); html("</div>\n"); } char *cgit_rooturl() { - if (cgit_virtual_root) - return fmt("%s/", cgit_virtual_root); + if (ctx.cfg.virtual_root) + return fmt("%s/", ctx.cfg.virtual_root); else - return cgit_script_name; + return ctx.cfg.script_name; } char *cgit_repourl(const char *reponame) { - if (cgit_virtual_root) { - return fmt("%s/%s/", cgit_virtual_root, 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) { char *tmp; char *delim; - if (cgit_virtual_root) { - tmp = fmt("%s/%s/%s/%s", cgit_virtual_root, reponame, + if (ctx.cfg.virtual_root) { + tmp = fmt("%s/%s/%s/%s", ctx.cfg.virtual_root, reponame, pagename, (filename ? filename:"")); delim = "?"; } else { tmp = fmt("?url=%s/%s/%s", reponame, pagename, (filename ? filename : "")); delim = "&"; } if (query) tmp = fmt("%s%s%s", tmp, delim, query); return tmp; } char *cgit_pageurl(const char *reponame, const char *pagename, const char *query) { return cgit_fileurl(reponame,pagename,0,query); } const char *cgit_repobasename(const char *reponame) { /* I assume we don't need to store more than one repo basename */ static char rvbuf[1024]; int p; const char *rv; strncpy(rvbuf,reponame,sizeof(rvbuf)); if(rvbuf[sizeof(rvbuf)-1]) die("cgit_repobasename: truncated repository name '%s'", reponame); p = strlen(rvbuf)-1; /* strip trailing slashes */ while(p && rvbuf[p]=='/') rvbuf[p--]=0; /* strip trailing .git */ if(p>=3 && !strncmp(&rvbuf[p-3],".git",4)) { p -= 3; rvbuf[p--] = 0; } /* strip more trailing slashes if any */ while( p && rvbuf[p]=='/') rvbuf[p--]=0; /* find last slash in the remaining string */ rv = strrchr(rvbuf,'/'); if(rv) return ++rv; return rvbuf; } char *cgit_currurl() { - if (!cgit_virtual_root) - return cgit_script_name; + if (!ctx.cfg.virtual_root) + return ctx.cfg.script_name; else if (ctx.qry.page) - return fmt("%s/%s/%s/", cgit_virtual_root, ctx.qry.repo, ctx.qry.page); + return fmt("%s/%s/%s/", ctx.cfg.virtual_root, ctx.qry.repo, ctx.qry.page); else if (ctx.qry.repo) - return fmt("%s/%s/", cgit_virtual_root, ctx.qry.repo); + return fmt("%s/%s/", ctx.cfg.virtual_root, ctx.qry.repo); else - return fmt("%s/", cgit_virtual_root); + return fmt("%s/", ctx.cfg.virtual_root); } static char *repolink(char *title, char *class, char *page, char *head, char *path) { char *delim = "?"; html("<a"); if (title) { html(" title='"); html_attr(title); html("'"); } if (class) { html(" class='"); html_attr(class); html("'"); } html(" href='"); - if (cgit_virtual_root) { - html_attr(cgit_virtual_root); - if (cgit_virtual_root[strlen(cgit_virtual_root) - 1] != '/') + if (ctx.cfg.virtual_root) { + html_attr(ctx.cfg.virtual_root); + if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/') html("/"); html_attr(cgit_repo->url); if (cgit_repo->url[strlen(cgit_repo->url) - 1] != '/') html("/"); if (page) { html(page); html("/"); if (path) html_attr(path); } } else { - html(cgit_script_name); + html(ctx.cfg.script_name); html("?url="); html_attr(cgit_repo->url); if (cgit_repo->url[strlen(cgit_repo->url) - 1] != '/') html("/"); if (page) { html(page); html("/"); if (path) html_attr(path); } delim = "&"; } if (head && strcmp(head, cgit_repo->defbranch)) { html(delim); html("h="); html_attr(head); delim = "&"; } return fmt("%s", delim); } static void reporevlink(char *page, char *name, char *title, char *class, char *head, char *rev, char *path) { char *delim; delim = repolink(title, class, page, head, path); if (rev && strcmp(rev, ctx.qry.head)) { html(delim); html("id="); html_attr(rev); } html("'>"); html_txt(name); html("</a>"); } void cgit_tree_link(char *name, char *title, char *class, char *head, char *rev, char *path) { reporevlink("tree", name, title, class, head, rev, path); } void cgit_log_link(char *name, char *title, char *class, char *head, char *rev, char *path, int ofs, char *grep, char *pattern) { char *delim; delim = repolink(title, class, "log", head, path); if (rev && strcmp(rev, ctx.qry.head)) { html(delim); html("id="); html_attr(rev); delim = "&"; } if (grep && pattern) { html(delim); html("qt="); html_attr(grep); delim = "&"; html(delim); html("q="); html_attr(pattern); } if (ofs > 0) { html(delim); html("ofs="); htmlf("%d", ofs); } html("'>"); html_txt(name); html("</a>"); } void cgit_commit_link(char *name, char *title, char *class, char *head, char *rev) { - if (strlen(name) > cgit_max_msg_len && cgit_max_msg_len >= 15) { - name[cgit_max_msg_len] = '\0'; - name[cgit_max_msg_len - 1] = '.'; - name[cgit_max_msg_len - 2] = '.'; - name[cgit_max_msg_len - 3] = '.'; + if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) { + name[ctx.cfg.max_msg_len] = '\0'; + name[ctx.cfg.max_msg_len - 1] = '.'; + name[ctx.cfg.max_msg_len - 2] = '.'; + name[ctx.cfg.max_msg_len - 3] = '.'; } reporevlink("commit", name, title, class, head, rev, NULL); } void cgit_refs_link(char *name, char *title, char *class, char *head, char *rev, char *path) { reporevlink("refs", name, title, class, head, rev, path); } void cgit_snapshot_link(char *name, char *title, char *class, char *head, char *rev, char *archivename) { reporevlink("snapshot", name, title, class, head, rev, archivename); } void cgit_diff_link(char *name, char *title, char *class, char *head, char *new_rev, char *old_rev, char *path) { char *delim; delim = repolink(title, class, "diff", head, path); if (new_rev && strcmp(new_rev, ctx.qry.head)) { html(delim); html("id="); html_attr(new_rev); delim = "&"; } if (old_rev) { html(delim); html("id2="); html_attr(old_rev); } html("'>"); html_txt(name); html("</a>"); } void cgit_patch_link(char *name, char *title, char *class, char *head, char *rev) { reporevlink("patch", name, title, class, head, rev, NULL); } void cgit_object_link(struct object *obj) { char *page, *arg, *url; @@ -329,242 +329,242 @@ void cgit_print_age(time_t t, time_t max_relative, char *format) if (secs > max_relative && max_relative >= 0) { cgit_print_date(t, format); return; } if (secs < TM_HOUR * 2) { htmlf("<span class='age-mins'>%.0f min.</span>", secs * 1.0 / TM_MIN); return; } if (secs < TM_DAY * 2) { htmlf("<span class='age-hours'>%.0f hours</span>", secs * 1.0 / TM_HOUR); return; } if (secs < TM_WEEK * 2) { htmlf("<span class='age-days'>%.0f days</span>", secs * 1.0 / TM_DAY); return; } if (secs < TM_MONTH * 2) { htmlf("<span class='age-weeks'>%.0f weeks</span>", secs * 1.0 / TM_WEEK); return; } if (secs < TM_YEAR * 2) { htmlf("<span class='age-months'>%.0f months</span>", secs * 1.0 / TM_MONTH); return; } htmlf("<span class='age-years'>%.0f years</span>", secs * 1.0 / TM_YEAR); } void cgit_print_docstart(char *title, struct cacheitem *item) { html("Content-Type: text/html; charset=" PAGE_ENCODING "\n"); htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); htmlf("Expires: %s\n", http_date(item->st.st_mtime + ttl_seconds(item->ttl))); html("\n"); html(cgit_doctype); html("<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>\n"); html("<head>\n"); html("<title>"); html_txt(title); html("</title>\n"); htmlf("<meta name='generator' content='cgit %s'/>\n", cgit_version); - if (cgit_robots && *cgit_robots) - htmlf("<meta name='robots' content='%s'/>\n", cgit_robots); + if (ctx.cfg.robots && *ctx.cfg.robots) + htmlf("<meta name='robots' content='%s'/>\n", ctx.cfg.robots); html("<link rel='stylesheet' type='text/css' href='"); - html_attr(cgit_css); + html_attr(ctx.cfg.css); html("'/>\n"); html("</head>\n"); html("<body>\n"); } void cgit_print_docend() { html("</td>\n</tr>\n</table>\n</body>\n</html>\n"); } int print_branch_option(const char *refname, const unsigned char *sha1, int flags, void *cb_data) { char *name = (char *)refname; html_option(name, name, ctx.qry.head); return 0; } int print_archive_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data) { struct tag *tag; struct taginfo *info; struct object *obj; char buf[256], *url; unsigned char fileid[20]; int *header = (int *)cb_data; if (prefixcmp(refname, "refs/archives")) return 0; strncpy(buf, refname+14, sizeof(buf)); obj = parse_object(sha1); if (!obj) return 1; if (obj->type == OBJ_TAG) { tag = lookup_tag(sha1); if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) return 0; hashcpy(fileid, tag->tagged->sha1); } else if (obj->type != OBJ_BLOB) { return 0; } else { hashcpy(fileid, sha1); } if (!*header) { html("<h1>download</h1>\n"); *header = 1; } url = cgit_pageurl(ctx.qry.repo, "blob", fmt("id=%s&path=%s", sha1_to_hex(fileid), buf)); html_link_open(url, NULL, "menu"); html_txt(strlpart(buf, 20)); html_link_close(); return 0; } void add_hidden_formfields(int incl_head, int incl_search, char *page) { char *url; - if (!cgit_virtual_root) { + if (!ctx.cfg.virtual_root) { url = fmt("%s/%s", ctx.qry.repo, page); if (ctx.qry.path) url = fmt("%s/%s", url, ctx.qry.path); html_hidden("url", url); } if (incl_head && strcmp(ctx.qry.head, cgit_repo->defbranch)) html_hidden("h", ctx.qry.head); if (ctx.qry.sha1) html_hidden("id", ctx.qry.sha1); if (ctx.qry.sha2) html_hidden("id2", ctx.qry.sha2); if (incl_search) { if (ctx.qry.grep) html_hidden("qt", ctx.qry.grep); if (ctx.qry.search) html_hidden("q", ctx.qry.search); } } void cgit_print_pageheader(char *title, int show_search) { static const char *default_info = "This is cgit, a fast webinterface for git repositories"; int header = 0; char *url; html("<table id='layout' summary=''>\n"); html("<tr><td id='sidebar'>\n"); html("<table class='sidebar' cellspacing='0' summary=''>\n"); html("<tr><td class='sidebar'>\n<a href='"); html_attr(cgit_rooturl()); htmlf("'><img src='%s' alt='cgit'/></a>\n", - cgit_logo); + ctx.cfg.logo); html("</td></tr>\n<tr><td class='sidebar'>\n"); if (ctx.qry.repo) { html("<h1 class='first'>"); html_txt(strrpart(cgit_repo->name, 20)); html("</h1>\n"); html_txt(cgit_repo->desc); if (cgit_repo->owner) { html("<h1>owner</h1>\n"); html_txt(cgit_repo->owner); } html("<h1>navigate</h1>\n"); reporevlink(NULL, "summary", NULL, "menu", ctx.qry.head, NULL, NULL); cgit_log_link("log", NULL, "menu", ctx.qry.head, NULL, NULL, 0, NULL, NULL); cgit_tree_link("tree", NULL, "menu", ctx.qry.head, ctx.qry.sha1, NULL); cgit_commit_link("commit", NULL, "menu", ctx.qry.head, ctx.qry.sha1); cgit_diff_link("diff", NULL, "menu", ctx.qry.head, ctx.qry.sha1, ctx.qry.sha2, NULL); cgit_patch_link("patch", NULL, "menu", ctx.qry.head, ctx.qry.sha1); for_each_ref(print_archive_ref, &header); - if (cgit_repo->clone_url || cgit_clone_prefix) { + if (cgit_repo->clone_url || ctx.cfg.clone_prefix) { html("<h1>clone</h1>\n"); if (cgit_repo->clone_url) url = cgit_repo->clone_url; else - url = fmt("%s%s", cgit_clone_prefix, + url = fmt("%s%s", ctx.cfg.clone_prefix, cgit_repo->url); html("<a class='menu' href='"); html_attr(url); html("' title='"); html_attr(url); html("'>\n"); html_txt(strrpart(url, 20)); html("</a>\n"); } html("<h1>branch</h1>\n"); html("<form method='get' action=''>\n"); add_hidden_formfields(0, 1, ctx.qry.page); // html("<table summary='branch selector' class='grid'><tr><td id='branch-dropdown-cell'>"); html("<select name='h' onchange='this.form.submit();'>\n"); for_each_branch_ref(print_branch_option, ctx.qry.head); html("</select>\n"); // html("</td><td>"); html("<noscript><input type='submit' id='switch-btn' value='switch'/></noscript>\n"); // html("</td></tr></table>"); html("</form>\n"); html("<h1>search</h1>\n"); html("<form method='get' action='"); - if (cgit_virtual_root) + if (ctx.cfg.virtual_root) html_attr(cgit_fileurl(ctx.qry.repo, "log", ctx.qry.path, NULL)); html("'>\n"); add_hidden_formfields(1, 0, "log"); html("<select name='qt'>\n"); html_option("grep", "log msg", ctx.qry.grep); html_option("author", "author", ctx.qry.grep); html_option("committer", "committer", ctx.qry.grep); html("</select>\n"); html("<input class='txt' type='text' name='q' value='"); html_attr(ctx.qry.search); html("'/>\n"); html("</form>\n"); } else { - if (!cgit_index_info || html_include(cgit_index_info)) + if (!ctx.cfg.index_info || html_include(ctx.cfg.index_info)) html(default_info); } html("</td></tr></table></td>\n"); html("<td id='content'>\n"); } void cgit_print_snapshot_start(const char *mimetype, const char *filename, struct cacheitem *item) { htmlf("Content-Type: %s\n", mimetype); htmlf("Content-Disposition: inline; filename=\"%s\"\n", filename); htmlf("Last-Modified: %s\n", http_date(item->st.st_mtime)); htmlf("Expires: %s\n", http_date(item->st.st_mtime + ttl_seconds(item->ttl))); html("\n"); } /* vim:set sw=8: */ diff --git a/ui-summary.c b/ui-summary.c index bbd4464..0a44994 100644 --- a/ui-summary.c +++ b/ui-summary.c @@ -142,59 +142,59 @@ void cgit_print_branches(int maxcount) for_each_branch_ref(cgit_refs_cb, &list); if (maxcount == 0 || maxcount > list.count) maxcount = list.count; if (maxcount < list.count) { qsort(list.refs, list.count, sizeof(*list.refs), cmp_branch_age); qsort(list.refs, maxcount, sizeof(*list.refs), cmp_ref_name); } for(i=0; i<maxcount; i++) print_branch(list.refs[i]); if (maxcount < list.count) print_refs_link("heads"); } void cgit_print_tags(int maxcount) { struct reflist list; int i; header = 0; list.refs = NULL; list.alloc = list.count = 0; for_each_tag_ref(cgit_refs_cb, &list); if (list.count == 0) return; qsort(list.refs, list.count, sizeof(*list.refs), cmp_tag_age); if (!maxcount) maxcount = list.count; else if (maxcount > list.count) maxcount = list.count; print_tag_header(); for(i=0; i<maxcount; i++) print_tag(list.refs[i]); if (maxcount < list.count) print_refs_link("tags"); } void cgit_print_summary() { if (cgit_repo->readme) { html("<div id='summary'>"); html_include(cgit_repo->readme); html("</div>"); } - if (cgit_summary_log > 0) - cgit_print_log(ctx.qry.head, 0, cgit_summary_log, NULL, + if (ctx.cfg.summary_log > 0) + cgit_print_log(ctx.qry.head, 0, ctx.cfg.summary_log, NULL, NULL, NULL, 0); html("<table summary='repository info' class='list nowrap'>"); - if (cgit_summary_log > 0) + if (ctx.cfg.summary_log > 0) html("<tr class='nohover'><td colspan='4'> </td></tr>"); - cgit_print_branches(cgit_summary_branches); + cgit_print_branches(ctx.cfg.summary_branches); html("<tr class='nohover'><td colspan='4'> </td></tr>"); - cgit_print_tags(cgit_summary_tags); + cgit_print_tags(ctx.cfg.summary_tags); html("</table>"); } |