+static void site_url(const char *page, const char *search, int ofs)
+{
+ char *delim = "?";
+
+ if (ctx.cfg.virtual_root) {
+ html_attr(ctx.cfg.virtual_root);
+ if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/')
+ html("/");
+ } else
+ html(ctx.cfg.script_name);
+
+ if (page) {
+ htmlf("?p=%s", page);
+ delim = "&";
+ }
+ if (search) {
+ html(delim);
+ html("q=");
+ html_attr(search);
+ delim = "&";
+ }
+ if (ofs) {
+ html(delim);
+ htmlf("ofs=%d", ofs);
+ }
+}
+
+static void site_link(const char *page, const char *name, const char *title,
+ const char *class, const char *search, int ofs)
+{
+ html("<a");
+ if (title) {
+ html(" title='");
+ html_attr(title);
+ html("'");
+ }
+ if (class) {
+ html(" class='");
+ html_attr(class);
+ html("'");
+ }
+ html(" href='");
+ site_url(page, search, ofs);
+ html("'>");
+ html_txt(name);
+ html("</a>");
+}
+
+void cgit_index_link(const char *name, const char *title, const char *class,
+ const char *pattern, int ofs)
+{
+ site_link(NULL, name, title, class, pattern, ofs);
+}
+
+static char *repolink(const char *title, const char *class, const char *page,
+ const char *head, const char *path)