X-Git-Url: https://git.cameronkatri.com/cgit.git/blobdiff_plain/db4b735464aa9a3a329494b7f042413a65e182f2..45c87ca1c32dcd5ffd4a681fadf05627d9ce7770:/ui-shared.c diff --git a/ui-shared.c b/ui-shared.c index f8e5bef..76aac60 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -11,7 +11,7 @@ #include "cmd.h" #include "html.h" -const char cgit_doctype[] = +static const char cgit_doctype[] = "\n"; @@ -46,7 +46,7 @@ void cgit_vprint_error(const char *fmt, va_list ap) html("\n"); } -const char *cgit_httpscheme() +const char *cgit_httpscheme(void) { if (ctx.env.https && !strcmp(ctx.env.https, "on")) return "https://"; @@ -54,18 +54,29 @@ const char *cgit_httpscheme() return "http://"; } -const char *cgit_hosturl() +char *cgit_hosturl(void) { if (ctx.env.http_host) - return ctx.env.http_host; + return xstrdup(ctx.env.http_host); if (!ctx.env.server_name) return NULL; if (!ctx.env.server_port || atoi(ctx.env.server_port) == 80) - return ctx.env.server_name; + return xstrdup(ctx.env.server_name); return fmtalloc("%s:%s", ctx.env.server_name, ctx.env.server_port); } -const char *cgit_rooturl() +char *cgit_currenturl(void) +{ + if (!ctx.qry.url) + return xstrdup(cgit_rooturl()); + const char *root = cgit_rooturl(); + size_t len = strlen(root); + if (len && root[len - 1] == '/') + return fmtalloc("%s%s", root, ctx.qry.url); + return fmtalloc("%s/%s", root, ctx.qry.url); +} + +const char *cgit_rooturl(void) { if (ctx.cfg.virtual_root) return ctx.cfg.virtual_root; @@ -73,9 +84,9 @@ const char *cgit_rooturl() return ctx.cfg.script_name; } -const char *cgit_loginurl() +const char *cgit_loginurl(void) { - static const char *login_url = 0; + static const char *login_url; if (!login_url) login_url = fmtalloc("%s?p=login", cgit_rooturl()); return login_url; @@ -112,7 +123,7 @@ char *cgit_fileurl(const char *reponame, const char *pagename, char *cgit_pageurl(const char *reponame, const char *pagename, const char *query) { - return cgit_fileurl(reponame, pagename, 0, query); + return cgit_fileurl(reponame, pagename, NULL, query); } const char *cgit_repobasename(const char *reponame) @@ -140,14 +151,17 @@ const char *cgit_repobasename(const char *reponame) return rvbuf; } -static void site_url(const char *page, const char *search, const char *sort, int ofs) +static void site_url(const char *page, const char *search, const char *sort, int ofs, int always_root) { char *delim = "?"; - if (!page) - html_attr(ctx.qry.url); - else + if (always_root || page) html_attr(cgit_rooturl()); + else { + char *currenturl = cgit_currenturl(); + html_attr(currenturl); + free(currenturl); + } if (page) { htmlf("?p=%s", page); @@ -172,7 +186,7 @@ static void site_url(const char *page, const char *search, const char *sort, int } static void site_link(const char *page, const char *name, const char *title, - const char *class, const char *search, const char *sort, int ofs) + const char *class, const char *search, const char *sort, int ofs, int always_root) { html(""); html_txt(name); html(""); } void cgit_index_link(const char *name, const char *title, const char *class, - const char *pattern, const char *sort, int ofs) + const char *pattern, const char *sort, int ofs, int always_root) { - site_link(NULL, name, title, class, pattern, sort, ofs); + site_link(NULL, name, title, class, pattern, sort, ofs, always_root); } static char *repolink(const char *title, const char *class, const char *page, @@ -292,7 +306,8 @@ void cgit_plain_link(const char *name, const char *title, const char *class, void cgit_log_link(const char *name, const char *title, const char *class, const char *head, const char *rev, const char *path, - int ofs, const char *grep, const char *pattern, int showmsg) + int ofs, const char *grep, const char *pattern, int showmsg, + int follow) { char *delim; @@ -321,6 +336,11 @@ void cgit_log_link(const char *name, const char *title, const char *class, if (showmsg) { html(delim); html("showmsg=1"); + delim = "&"; + } + if (follow) { + html(delim); + html("follow=1"); } html("'>"); html_txt(name); @@ -362,6 +382,10 @@ void cgit_commit_link(char *name, const char *title, const char *class, html("ignorews=1"); delim = "&"; } + if (ctx.qry.follow) { + html(delim); + html("follow=1"); + } html("'>"); if (name[0] != '\0') html_txt(name); @@ -418,6 +442,10 @@ void cgit_diff_link(const char *name, const char *title, const char *class, html("ignorews=1"); delim = "&"; } + if (ctx.qry.follow) { + html(delim); + html("follow=1"); + } html("'>"); html_txt(name); html(""); @@ -439,7 +467,7 @@ static void cgit_self_link(char *name, const char *title, const char *class) { if (!strcmp(ctx.qry.page, "repolist")) cgit_index_link(name, title, class, ctx.qry.search, ctx.qry.sort, - ctx.qry.ofs); + ctx.qry.ofs, 1); else if (!strcmp(ctx.qry.page, "summary")) cgit_summary_link(name, title, class, ctx.qry.head); else if (!strcmp(ctx.qry.page, "tag")) @@ -458,7 +486,7 @@ static void cgit_self_link(char *name, const char *title, const char *class) ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL, ctx.qry.path, ctx.qry.ofs, ctx.qry.grep, ctx.qry.search, - ctx.qry.showmsg); + ctx.qry.showmsg, ctx.qry.follow); else if (!strcmp(ctx.qry.page, "commit")) cgit_commit_link(name, title, class, ctx.qry.head, ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL, @@ -497,7 +525,7 @@ void cgit_object_link(struct object *obj) { char *page, *shortrev, *fullrev, *name; - fullrev = sha1_to_hex(obj->sha1); + fullrev = oid_to_hex(&obj->oid); shortrev = xstrdup(fullrev); shortrev[10] = '\0'; if (obj->type == OBJ_COMMIT) { @@ -548,63 +576,66 @@ void cgit_submodule_link(const char *class, char *path, const char *rev) item = lookup_path(list, path); } } - html("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); + if (item || ctx.repo->module_link) { + html("util, rev); + } else { + dir = strrchr(path, '/'); + if (dir) + dir++; + else + dir = path; + html_attrf(ctx.repo->module_link, dir, rev); + } + html("'>"); + html_txt(path); + html(""); } else { - html("#"); + html(""); + html_txt(path); + html(""); } - html("'>"); - html_txt(path); - html(""); html_txtf(" @ %.7s", rev); if (item && tail) path[len - 1] = tail; } -void cgit_print_date(time_t secs, const char *format, int local_time) +static const char *fmt_date(time_t secs, const char *format, int local_time) { - char buf[64]; + static char buf[64]; struct tm *time; if (!secs) - return; + return ""; if (local_time) time = localtime(&secs); else time = gmtime(&secs); strftime(buf, sizeof(buf)-1, format, time); - html_txt(buf); + return buf; +} + +void cgit_print_date(time_t secs, const char *format, int local_time) +{ + html_txt(fmt_date(secs, format, local_time)); } static void print_rel_date(time_t t, double value, const char *class, const char *suffix) { - char buf[64]; - struct tm *time; - - if (ctx.cfg.local_time) - time = localtime(&t); - else - time = gmtime(&t); - strftime(buf, sizeof(buf) - 1, FMT_LONGDATE, time); - htmlf("%.0f %s", value, suffix); } -void cgit_print_age(time_t t, time_t max_relative, const char *format) +void cgit_print_age(time_t t, time_t max_relative) { time_t now, secs; @@ -616,7 +647,11 @@ void cgit_print_age(time_t t, time_t max_relative, const char *format) secs = 0; if (secs > max_relative && max_relative >= 0) { - cgit_print_date(t, format, ctx.cfg.local_time); + html(""); + cgit_print_date(t, FMT_SHORTDATE, ctx.cfg.local_time); + html(""); return; } @@ -657,9 +692,11 @@ void cgit_print_http_headers(void) htmlf("Content-Type: %s\n", ctx.page.mimetype); if (ctx.page.size) htmlf("Content-Length: %zd\n", ctx.page.size); - if (ctx.page.filename) - htmlf("Content-Disposition: inline; filename=\"%s\"\n", - ctx.page.filename); + if (ctx.page.filename) { + html("Content-Disposition: inline; filename=\""); + html_header_arg_in_quotes(ctx.page.filename); + html("\"\n"); + } if (!ctx.env.authenticated) html("Cache-Control: no-cache, no-store\n"); htmlf("Last-Modified: %s\n", http_date(ctx.page.modified)); @@ -671,6 +708,15 @@ void cgit_print_http_headers(void) exit(0); } +void cgit_redirect(const char *url, bool permanent) +{ + htmlf("Status: %d %s\n", permanent ? 301 : 302, permanent ? "Moved" : "Found"); + html("Location: "); + html_url_path(url); + html("\n\n"); + exit(0); +} + static void print_rel_vcs_link(const char *url) { html("\n"); html("
\n"); @@ -707,16 +753,19 @@ void cgit_print_docstart(void) html("'/>\n"); } if (host && ctx.repo && ctx.qry.head) { + char *fileurl; struct strbuf sb = STRBUF_INIT; strbuf_addf(&sb, "h=%s", ctx.qry.head); html("\n"); strbuf_release(&sb); + free(fileurl); } if (ctx.repo) cgit_add_clone_urls(print_rel_vcs_link); @@ -726,9 +775,10 @@ void cgit_print_docstart(void) html("\n"); if (ctx.cfg.header) html_include(ctx.cfg.header); + free(host); } -void cgit_print_docend() +void cgit_print_docend(void) { html(" \n"); if (ctx.cfg.embedded) { @@ -749,6 +799,33 @@ void cgit_print_docend() html("\n\n"); } +void cgit_print_error_page(int code, const char *msg, const char *fmt, ...) +{ + va_list ap; + ctx.page.expires = ctx.cfg.cache_dynamic_ttl; + ctx.page.status = code; + ctx.page.statusmsg = msg; + cgit_print_http_headers(); + cgit_print_docstart(); + cgit_print_pageheader(); + va_start(ap, fmt); + cgit_vprint_error(fmt, ap); + va_end(ap); + cgit_print_docend(); +} + +void cgit_print_layout_start(void) +{ + cgit_print_http_headers(); + cgit_print_docstart(); + cgit_print_pageheader(); +} + +void cgit_print_layout_end(void) +{ + cgit_print_docend(); +} + static void add_clone_urls(void (*fn)(const char *), char *txt, char *suffix) { struct strbuf **url_list = strbuf_split_str(txt, ' ', 0); @@ -774,7 +851,7 @@ void cgit_add_clone_urls(void (*fn)(const char *)) add_clone_urls(fn, ctx.cfg.clone_prefix, ctx.repo->url); } -static int print_branch_option(const char *refname, const unsigned char *sha1, +static int print_branch_option(const char *refname, const struct object_id *oid, int flags, void *cb_data) { char *name = (char *)refname; @@ -816,6 +893,9 @@ void cgit_add_hidden_formfields(int incl_head, int incl_search, static const char *hc(const char *page) { + if (!ctx.qry.page) + return NULL; + return strcmp(ctx.qry.page, page) ? NULL : "active"; } @@ -868,7 +948,7 @@ static void print_header(void) html("