Lars HjemliMerge branch 'stable'1b09cbd15 years agoHistory
919 lines · 23.5 KB · C
RawDownload
/* 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"#include "cmd.h"#include "html.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", "Nov", "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);} void cgit_print_error(const char *msg){	html("<div class='error'>");	html_txt(msg);	html("</div>\n");} char *cgit_httpscheme(){	if (ctx.env.https && !strcmp(ctx.env.https, "on"))		return "https://";	else		return "http://";} char *cgit_hosturl(){	if (ctx.env.http_host)		return 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(fmt("%s:%s", ctx.env.server_name, ctx.env.server_port));} char *cgit_rooturl(){	if (ctx.cfg.virtual_root)		return fmt("%s/", ctx.cfg.virtual_root);	else		return ctx.cfg.script_name;} char *cgit_repourl(const char *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 (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 (!ctx.cfg.virtual_root)		return ctx.cfg.script_name;	else if (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/", ctx.cfg.virtual_root, ctx.qry.repo);	else		return fmt("%s/", ctx.cfg.virtual_root);} 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){	char *delim = "?"; 	html("<a");	if (title) {		html(" title='");		html_attr(title);		html("'");	}	if (class) {		html(" class='");		html_attr(class);		html("'");	}	html(" href='");	if (ctx.cfg.virtual_root) {		html_url_path(ctx.cfg.virtual_root);		if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/')			html("/");		html_url_path(ctx.repo->url);		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')			html("/");		if (page) {			html_url_path(page);			html("/");			if (path)				html_url_path(path);		}	} else {		html(ctx.cfg.script_name);		html("?url=");		html_url_arg(ctx.repo->url);		if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')			html("/");		if (page) {			html_url_arg(page);			html("/");			if (path)				html_url_arg(path);		}		delim = "&amp;";	}	if (head && strcmp(head, ctx.repo->defbranch)) {		html(delim);		html("h=");		html_url_arg(head);		delim = "&amp;";	}	return fmt("%s", delim);} static void reporevlink(const char *page, const char *name, const char *title,			const char *class, const char *head, const char *rev,			const char *path){	char *delim; 	delim = repolink(title, class, page, head, path);	if (rev && ctx.qry.head != NULL && strcmp(rev, ctx.qry.head)) {		html(delim);		html("id=");		html_url_arg(rev);	}	html("'>");	html_txt(name);	html("</a>");} void cgit_summary_link(const char *name, const char *title, const char *class,		       const char *head){	reporevlink(NULL, name, title, class, head, NULL, NULL);} void cgit_tag_link(const char *name, const char *title, const char *class,		   const char *head, const char *rev){	reporevlink("tag", name, title, class, head, rev, NULL);} void cgit_tree_link(const char *name, const char *title, const char *class,		    const char *head, const char *rev, const char *path){	reporevlink("tree", name, title, class, head, rev, path);} void cgit_plain_link(const char *name, const char *title, const char *class,		     const char *head, const char *rev, const char *path){	reporevlink("plain", 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){	char *delim; 	delim = repolink(title, class, "log", head, path);	if (rev && strcmp(rev, ctx.qry.head)) {		html(delim);		html("id=");		html_url_arg(rev);		delim = "&";	}	if (grep && pattern) {		html(delim);		html("qt=");		html_url_arg(grep);		delim = "&";		html(delim);		html("q=");		html_url_arg(pattern);	}	if (ofs > 0) {		html(delim);		html("ofs=");		htmlf("%d", ofs);		delim = "&";	}	if (showmsg) {		html(delim);		html("showmsg=1");	}	html("'>");	html_txt(name);	html("</a>");} void cgit_commit_link(char *name, const char *title, const char *class,		      const char *head, const char *rev, const char *path,		      int toggle_ssdiff){	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] = '.';	} 	char *delim; 	delim = repolink(title, class, "commit", head, path);	if (rev && strcmp(rev, ctx.qry.head)) {		html(delim);		html("id=");		html_url_arg(rev);		delim = "&amp;";	}	if ((ctx.qry.ssdiff && !toggle_ssdiff) || (!ctx.qry.ssdiff && toggle_ssdiff)) {		html(delim);		html("ss=1");		delim = "&amp;";	}	if (ctx.qry.context > 0 && ctx.qry.context != 3) {		html(delim);		html("context=");		htmlf("%d", ctx.qry.context);		delim = "&amp;";	}	if (ctx.qry.ignorews) {		html(delim);		html("ignorews=1");		delim = "&amp;";	}	html("'>");	html_txt(name);	html("</a>");} void cgit_refs_link(const char *name, const char *title, const char *class,		    const char *head, const char *rev, const char *path){	reporevlink("refs", name, title, class, head, rev, path);} void cgit_snapshot_link(const char *name, const char *title, const char *class,			const char *head, const char *rev,			const char *archivename){	reporevlink("snapshot", name, title, class, head, rev, archivename);} void cgit_diff_link(const char *name, const char *title, const char *class,		    const char *head, const char *new_rev, const char *old_rev,		    const char *path, int toggle_ssdiff){	char *delim; 	delim = repolink(title, class, "diff", head, path);	if (new_rev && ctx.qry.head != NULL && strcmp(new_rev, ctx.qry.head)) {		html(delim);		html("id=");		html_url_arg(new_rev);		delim = "&amp;";	}	if (old_rev) {		html(delim);		html("id2=");		html_url_arg(old_rev);		delim = "&amp;";	}	if ((ctx.qry.ssdiff && !toggle_ssdiff) || (!ctx.qry.ssdiff && toggle_ssdiff)) {		html(delim);		html("ss=1");		delim = "&amp;";	}	if (ctx.qry.context > 0 && ctx.qry.context != 3) {		html(delim);		html("context=");		htmlf("%d", ctx.qry.context);		delim = "&amp;";	}	if (ctx.qry.ignorews) {		html(delim);		html("ignorews=1");		delim = "&amp;";	}	html("'>");	html_txt(name);	html("</a>");} void cgit_patch_link(const char *name, const char *title, const char *class,		     const char *head, const char *rev, const char *path){	reporevlink("patch", name, title, class, head, rev, path);} void cgit_stats_link(const char *name, const char *title, const char *class,		     const char *head, const char *path){	reporevlink("stats", name, title, class, head, NULL, path);} void cgit_self_link(char *name, const char *title, const char *class,		    struct cgit_context *ctx){	if (!strcmp(ctx->qry.page, "repolist"))		return cgit_index_link(name, title, class, ctx->qry.search,				       ctx->qry.ofs);	else if (!strcmp(ctx->qry.page, "summary"))		return cgit_summary_link(name, title, class, ctx->qry.head);	else if (!strcmp(ctx->qry.page, "tag"))		return cgit_tag_link(name, title, class, ctx->qry.head,				     ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL);	else if (!strcmp(ctx->qry.page, "tree"))		return cgit_tree_link(name, title, class, ctx->qry.head,				      ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,				      ctx->qry.path);	else if (!strcmp(ctx->qry.page, "plain"))		return 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, "log"))		return cgit_log_link(name, title, class, ctx->qry.head,				      ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,				      ctx->qry.path, ctx->qry.ofs,				      ctx->qry.grep, ctx->qry.search,				      ctx->qry.showmsg);	else if (!strcmp(ctx->qry.page, "commit"))		return cgit_commit_link(name, title, class, ctx->qry.head,				      ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,				      ctx->qry.path, 0);	else if (!strcmp(ctx->qry.page, "patch"))		return cgit_patch_link(name, title, class, ctx->qry.head,				      ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,				      ctx->qry.path);	else if (!strcmp(ctx->qry.page, "refs"))		return cgit_refs_link(name, title, class, ctx->qry.head,				      ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,				      ctx->qry.path);	else if (!strcmp(ctx->qry.page, "snapshot"))		return cgit_snapshot_link(name, title, class, ctx->qry.head,				      ctx->qry.has_sha1 ? ctx->qry.sha1 : NULL,				      ctx->qry.path);	else if (!strcmp(ctx->qry.page, "diff"))		return cgit_diff_link(name, title, class, ctx->qry.head,				      ctx->qry.sha1, ctx->qry.sha2,				      ctx->qry.path, 0);	else if (!strcmp(ctx->qry.page, "stats"))		return cgit_stats_link(name, title, class, ctx->qry.head,				      ctx->qry.path); 	/* Don't known how to make link for this page */	repolink(title, class, ctx->qry.page, ctx->qry.head, ctx->qry.path);	html("><!-- cgit_self_link() doesn't know how to make link for page '");	html_txt(ctx->qry.page);	html("' -->");	html_txt(name);	html("</a>");} void cgit_object_link(struct object *obj){	char *page, *shortrev, *fullrev, *name; 	fullrev = sha1_to_hex(obj->sha1);	shortrev = xstrdup(fullrev);	shortrev[10] = '\0';	if (obj->type == OBJ_COMMIT) {                cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL,				 ctx.qry.head, fullrev, NULL, 0);		return;	} else if (obj->type == OBJ_TREE)		page = "tree";	else if (obj->type == OBJ_TAG)		page = "tag";	else

Lines 1–500 of 919.