/* ui-shared.c: common web output functions
*
- * Copyright (C) 2006-2014 cgit Development Team <cgit@lists.zx2c4.com>
+ * Copyright (C) 2006-2017 cgit Development Team <cgit@lists.zx2c4.com>
*
* Licensed under GNU General Public License v2
* (see COPYING for full license text)
#include "ui-shared.h"
#include "cmd.h"
#include "html.h"
+#include "version.h"
static const char cgit_doctype[] =
"<!DOCTYPE html>\n";
static char rvbuf[1024];
int p;
const char *rv;
- strncpy(rvbuf, reponame, sizeof(rvbuf));
- if (rvbuf[sizeof(rvbuf)-1])
+ size_t len;
+
+ len = strlcpy(rvbuf, reponame, sizeof(rvbuf));
+ if (len >= sizeof(rvbuf))
die("cgit_repobasename: truncated repository name '%s'", reponame);
- p = strlen(rvbuf)-1;
+ p = len - 1;
/* strip trailing slashes */
- while (p && rvbuf[p] == '/') rvbuf[p--] = 0;
+ while (p && rvbuf[p] == '/')
+ rvbuf[p--] = '\0';
/* strip trailing .git */
if (p >= 3 && starts_with(&rvbuf[p-3], ".git")) {
- p -= 3; rvbuf[p--] = 0;
+ p -= 3;
+ rvbuf[p--] = '\0';
}
/* strip more trailing slashes if any */
- while ( p && rvbuf[p] == '/') rvbuf[p--] = 0;
+ while (p && rvbuf[p] == '/')
+ rvbuf[p--] = '\0';
/* find last slash in the remaining string */
- rv = strrchr(rvbuf,'/');
+ rv = strrchr(rvbuf, '/');
if (rv)
return ++rv;
return rvbuf;
}
+const char *cgit_snapshot_prefix(const struct cgit_repo *repo)
+{
+ if (repo->snapshot_prefix)
+ return repo->snapshot_prefix;
+
+ return cgit_repobasename(repo->url);
+}
+
static void site_url(const char *page, const char *search, const char *sort, int ofs, int always_root)
{
char *delim = "?";
reporevlink("plain", name, title, class, head, rev, path);
}
+void cgit_blame_link(const char *name, const char *title, const char *class,
+ const char *head, const char *rev, const char *path)
+{
+ reporevlink("blame", name, title, class, head, rev, path);
+}
+
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,
html("</a>");
}
-void cgit_commit_link(char *name, const char *title, const char *class,
+void cgit_commit_link(const char *name, const char *title, const char *class,
const char *head, const char *rev, const char *path)
{
char *delim;
- 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] = '.';
- }
-
delim = repolink(title, class, "commit", head, path);
if (rev && ctx.qry.head && strcmp(rev, ctx.qry.head)) {
html(delim);
html("follow=1");
}
html("'>");
- if (name[0] != '\0')
- html_txt(name);
- else
+ if (name[0] != '\0') {
+ if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) {
+ html_ntxt(name, ctx.cfg.max_msg_len - 3);
+ html("...");
+ } else
+ html_txt(name);
+ } else
html_txt("(no commit message)");
html("</a>");
}
cgit_plain_link(name, title, class, ctx.qry.head,
ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
ctx.qry.path);
+ else if (!strcmp(ctx.qry.page, "blame"))
+ cgit_blame_link(name, title, class, ctx.qry.head,
+ ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
+ ctx.qry.path);
else if (!strcmp(ctx.qry.page, "log"))
cgit_log_link(name, title, class, ctx.qry.head,
ctx.qry.has_sha1 ? ctx.qry.sha1 : NULL,
page = "tag";
else
page = "blob";
- name = fmt("%s %s...", typename(obj->type), shortrev);
+ name = fmt("%s %s...", type_name(obj->type), shortrev);
reporevlink(page, name, NULL, NULL, ctx.qry.head, fullrev, NULL);
}
cgit_add_clone_urls(print_rel_vcs_link);
if (ctx.cfg.head_include)
html_include(ctx.cfg.head_include);
+ if (ctx.repo && ctx.repo->extra_head_content)
+ html(ctx.repo->extra_head_content);
html("</head>\n");
html("<body>\n");
if (ctx.cfg.header)
if (ctx.cfg.footer)
html_include(ctx.cfg.footer);
else {
- htmlf("<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit %s</a> at ",
- cgit_version);
+ htmlf("<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit %s</a> "
+ "(<a href='https://git-scm.com/'>git %s</a>) at ", cgit_version, git_version_string);
html_txt(show_date(time(NULL), 0, cgit_date_mode(DATE_ISO8601)));
html("</div>\n");
}
} else {
if (ctx.cfg.root_desc)
html_txt(ctx.cfg.root_desc);
- else if (ctx.cfg.index_info)
- html_include(ctx.cfg.index_info);
}
html("</td></tr></table>\n");
}
cgit_log_link("log", NULL, hc("log"), ctx.qry.head,
NULL, ctx.qry.vpath, 0, NULL, NULL,
ctx.qry.showmsg, ctx.qry.follow);
- cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head,
- ctx.qry.sha1, ctx.qry.vpath);
+ if (ctx.qry.page && !strcmp(ctx.qry.page, "blame"))
+ cgit_blame_link("blame", NULL, hc("blame"), ctx.qry.head,
+ ctx.qry.sha1, ctx.qry.vpath);
+ else
+ cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head,
+ ctx.qry.sha1, ctx.qry.vpath);
cgit_commit_link("commit", NULL, hc("commit"),
ctx.qry.head, ctx.qry.sha1, ctx.qry.vpath);
cgit_diff_link("diff", NULL, hc("diff"), ctx.qry.head,
html_option("committer", "committer", ctx.qry.grep);
html_option("range", "range", ctx.qry.grep);
html("</select>\n");
- html("<input class='txt' type='text' size='10' name='q' value='");
+ html("<input class='txt' type='search' size='10' name='q' value='");
html_attr(ctx.qry.search);
html("'/>\n");
html("<input type='submit' value='search'/>\n");
html("<form method='get' action='");
html_attr(currenturl);
html("'>\n");
- html("<input type='text' name='q' size='10' value='");
+ html("<input type='search' name='q' size='10' value='");
html_attr(ctx.qry.search);
html("'/>\n");
html("<input type='submit' value='search'/>\n");
strbuf_addf(filename, "%s-%s", base, ref);
}
-void cgit_print_snapshot_links(const char *repo, const char *head,
- const char *hex, int snapshots)
+void cgit_print_snapshot_links(const struct cgit_repo *repo, const char *ref,
+ const char *separator)
{
- const struct cgit_snapshot_format* f;
+ const struct cgit_snapshot_format *f;
struct strbuf filename = STRBUF_INIT;
+ const char *basename;
size_t prefixlen;
- cgit_compose_snapshot_prefix(&filename, cgit_repobasename(repo), hex);
+ basename = cgit_snapshot_prefix(repo);
+ if (starts_with(ref, basename))
+ strbuf_addstr(&filename, ref);
+ else
+ cgit_compose_snapshot_prefix(&filename, basename, ref);
+
prefixlen = filename.len;
for (f = cgit_snapshot_formats; f->suffix; f++) {
- if (!(snapshots & f->bit))
+ if (!(repo->snapshots & cgit_snapshot_format_bit(f)))
continue;
strbuf_setlen(&filename, prefixlen);
strbuf_addstr(&filename, f->suffix);
cgit_snapshot_link(filename.buf, NULL, NULL, NULL, NULL,
filename.buf);
- html("<br/>");
+ if (cgit_snapshot_get_sig(ref, f)) {
+ strbuf_addstr(&filename, ".asc");
+ html(" (");
+ cgit_snapshot_link("sig", NULL, NULL, NULL, NULL,
+ filename.buf);
+ html(")");
+ } else if (starts_with(f->suffix, ".tar") && cgit_snapshot_get_sig(ref, &cgit_snapshot_formats[0])) {
+ strbuf_setlen(&filename, strlen(filename.buf) - strlen(f->suffix));
+ strbuf_addstr(&filename, ".tar.asc");
+ html(" (");
+ cgit_snapshot_link("sig", NULL, NULL, NULL, NULL,
+ filename.buf);
+ html(")");
+ }
+ html(separator);
}
strbuf_release(&filename);
}