diff options
| -rw-r--r-- | Makefile | 15 | ||||
| -rw-r--r-- | cgit.c | 9 | ||||
| -rw-r--r-- | cgit.css | 5 | ||||
| -rw-r--r-- | cgit.h | 1 | ||||
| -rw-r--r-- | cgitrc.5.txt | 15 | ||||
| -rwxr-xr-x | filters/syntax-highlighting.sh | 29 | ||||
| -rw-r--r-- | shared.c | 17 | ||||
| -rw-r--r-- | ui-repolist.c | 2 | ||||
| -rw-r--r-- | ui-shared.c | 11 | ||||
| -rw-r--r-- | ui-shared.h | 1 | ||||
| -rw-r--r-- | ui-tag.c | 24 | ||||
| -rw-r--r-- | ui-tree.c | 6 | 
12 files changed, 94 insertions, 41 deletions
| @@ -11,6 +11,9 @@ INSTALL = install  # Define NO_STRCASESTR if you don't have strcasestr.  # +# Define NO_OPENSSL to disable linking with OpenSSL and use bundled SHA1 +# implementation (slower). +#  # Define NEEDS_LIBICONV if linking with libc is not enough (eg. Darwin).  # @@ -68,7 +71,7 @@ endif  	$(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $< -EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto +EXTLIBS = git/libgit.a git/xdiff/lib.a -lz  OBJECTS =  OBJECTS += cache.o  OBJECTS += cgit.o @@ -124,6 +127,12 @@ endif  ifdef NO_STRCASESTR  	CFLAGS += -DNO_STRCASESTR  endif +ifdef NO_OPENSSL +	CFLAGS += -DNO_OPENSSL +	GIT_OPTIONS += NO_OPENSSL=1 +else +	EXTLIBS += -lcrypto +endif  cgit: $(OBJECTS) libgit  	$(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o cgit $(OBJECTS) $(EXTLIBS) @@ -133,8 +142,8 @@ cgit.o: VERSION  -include $(OBJECTS:.o=.d)  libgit: -	$(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 libgit.a -	$(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 xdiff/lib.a +	$(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 $(GIT_OPTIONS) libgit.a +	$(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 $(GIT_OPTIONS) xdiff/lib.a  test: all  	$(QUIET_SUBDIR0)tests $(QUIET_SUBDIR1) all @@ -68,9 +68,9 @@ void repo_config(struct cgit_repo *repo, const char *name, const char *value)  		repo->section = xstrdup(value);  	else if (!strcmp(name, "readme") && value != NULL) {  		if (*value == '/') -			ctx.repo->readme = xstrdup(value); +			repo->readme = xstrdup(value);  		else -			ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, value)); +			repo->readme = xstrdup(fmt("%s/%s", repo->path, value));  	} else if (ctx.cfg.enable_filter_overrides) {  		if (!strcmp(name, "about-filter"))  			repo->about_filter = new_filter(value, 0); @@ -165,6 +165,8 @@ void config_cb(const char *name, const char *value)  		ctx.cfg.max_msg_len = atoi(value);  	else if (!strcmp(name, "max-repodesc-length"))  		ctx.cfg.max_repodesc_len = atoi(value); +	else if (!strcmp(name, "max-blob-size")) +		ctx.cfg.max_blob_size = atoi(value);  	else if (!strcmp(name, "max-repo-count"))  		ctx.cfg.max_repo_count = atoi(value);  	else if (!strcmp(name, "max-commit-count")) @@ -211,6 +213,8 @@ static void querystring_cb(const char *name, const char *value)  	} else if (!strcmp(name, "p")) {  		ctx.qry.page = xstrdup(value);  	} else if (!strcmp(name, "url")) { +		if (*value == '/') +			value++;  		ctx.qry.url = xstrdup(value);  		cgit_parse_url(value);  	} else if (!strcmp(name, "qt")) { @@ -272,6 +276,7 @@ static void prepare_context(struct cgit_context *ctx)  	ctx->cfg.max_lock_attempts = 5;  	ctx->cfg.max_msg_len = 80;  	ctx->cfg.max_repodesc_len = 80; +	ctx->cfg.max_blob_size = 0;  	ctx->cfg.max_stats = 0;  	ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s";  	ctx->cfg.renamelimit = -1; @@ -162,6 +162,11 @@ table.list td a {  	color: black;  } +table.list td a.ls-dir { +	font-weight: bold; +	color: #00f; +} +  table.list td a:hover {  	color: #00f;  } @@ -186,6 +186,7 @@ struct cgit_config {  	int max_lock_attempts;  	int max_msg_len;  	int max_repodesc_len; +	int max_blob_size;  	int max_stats;  	int nocache;  	int noplainemail; diff --git a/cgitrc.5.txt b/cgitrc.5.txt index 252d546..70e4c78 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt @@ -1,3 +1,6 @@ +:man source:   cgit +:man manual:   cgit +  CGITRC(5)  ======== @@ -174,6 +177,10 @@ max-repodesc-length::  	Specifies the maximum number of repo description characters to display  	on the repository index page. Default value: "80". +max-blob-size:: +	Specifies the maximum size of a blob to display HTML for in KBytes. +	Default value: "0" (limit disabled). +  max-stats::  	Set the default maximum statistics period. Valid values are "week",  	"month", "quarter" and "year". If unspecified, statistics are @@ -425,8 +432,8 @@ mimetype.svg=image/svg+xml  ##  ## List of repositories. -## PS: Any repositories listed when repo.group is unset will not be -##     displayed under a group heading +## PS: Any repositories listed when section is unset will not be +##     displayed under a section heading  ## PPS: This list could be kept in a different file (e.g. '/etc/cgitrepos')  ##      and included like this:  ##        include=/etc/cgitrepos @@ -448,7 +455,7 @@ repo.readme=info/web/about.html  # The next repositories will be displayed under the 'extras' heading -repo.group=extras +section=extras  repo.url=baz @@ -461,7 +468,7 @@ repo.desc=the wizard of foo  # Add some mirrored repositories -repo.group=mirrors +section=mirrors  repo.url=git diff --git a/filters/syntax-highlighting.sh b/filters/syntax-highlighting.sh index 999ad0c..6b1c576 100755 --- a/filters/syntax-highlighting.sh +++ b/filters/syntax-highlighting.sh @@ -3,6 +3,10 @@  # tree-view by refering to this file with the source-filter or repo.source-  # filter options in cgitrc.  # +# This script requires a shell supporting the ${var##pattern} syntax. +# It is supported by at least dash and bash, however busybox environments +# might have to use an external call to sed instead. +#  # Note: the highlight command (http://www.andre-simon.de/) uses css for syntax  # highlighting, so you'll probably want something like the following included  # in your css file (generated by highlight 2.4.8 and adapted for cgit): @@ -20,20 +24,11 @@  # table.blob .kwc  { color:#000000; font-weight:bold; }  # table.blob .kwd  { color:#010181; } -case "$1" in -	*.c) -		highlight -f -I -X -S c -		;; -	*.h) -		highlight -f -I -X -S c -		;; -	*.sh) -		highlight -f -I -X -S sh -		;; -	*.css) -		highlight -f -I -X -S css -		;; -	*) -		highlight -f -I -X -S txt -		;; -esac +# store filename and extension in local vars +BASENAME="$1" +EXTENSION="${BASENAME##*.}" + +# map Makefile and Makefile.* to .mk +[ "${BASENAME%%.*}" == "Makefile" ] && EXTENSION=mk + +exec highlight --force -f -I -X -S $EXTENSION 2>/dev/null @@ -400,18 +400,25 @@ int cgit_close_filter(struct cgit_filter *filter)   */  int readfile(const char *path, char **buf, size_t *size)  { -	int fd; +	int fd, e;  	struct stat st;  	fd = open(path, O_RDONLY);  	if (fd == -1)  		return errno; -	if (fstat(fd, &st)) -		return errno; -	if (!S_ISREG(st.st_mode)) +	if (fstat(fd, &st)) { +		e = errno; +		close(fd); +		return e; +	} +	if (!S_ISREG(st.st_mode)) { +		close(fd);  		return EISDIR; +	}  	*buf = xmalloc(st.st_size + 1);  	*size = read_in_full(fd, *buf, st.st_size); +	e = errno;  	(*buf)[*size] = '\0'; -	return (*size == st.st_size ? 0 : errno); +	close(fd); +	return (*size == st.st_size ? 0 : e);  } diff --git a/ui-repolist.c b/ui-repolist.c index 3ef2e99..0a0b6ca 100644 --- a/ui-repolist.c +++ b/ui-repolist.c @@ -94,7 +94,7 @@ int is_in_url(struct cgit_repo *repo)  void print_sort_header(const char *title, const char *sort)  { -	htmlf("<th class='left'><a href='./?s=%s", sort); +	htmlf("<th class='left'><a href='%s?s=%s", cgit_rooturl(), sort);  	if (ctx.qry.search) {  		html("&q=");  		html_url_arg(ctx.qry.search); diff --git a/ui-shared.c b/ui-shared.c index de55eff..08ea003 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -20,7 +20,7 @@ static char *http_date(time_t t)  		{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};  	static char month[][4] =  		{"Jan", "Feb", "Mar", "Apr", "May", "Jun", -		 "Jul", "Aug", "Sep", "Oct", "Now", "Dec"}; +		 "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, @@ -782,13 +782,18 @@ void cgit_print_snapshot_links(const char *repo, const char *head,  			       const char *hex, int snapshots)  {  	const struct cgit_snapshot_format* f; +	char *prefix;      	char *filename; +	unsigned char sha1[20]; +	if (get_sha1(fmt("refs/tags/%s", hex), sha1) == 0 && +	    (hex[0] == 'v' || hex[0] == 'V') && isdigit(hex[1])) +		hex++; +	prefix = xstrdup(fmt("%s-%s", cgit_repobasename(repo), hex));  	for (f = cgit_snapshot_formats; f->suffix; f++) {  		if (!(snapshots & f->bit))  			continue; -		filename = fmt("%s-%s%s", cgit_repobasename(repo), hex, -			       f->suffix); +		filename = fmt("%s%s", prefix, f->suffix);  		cgit_snapshot_link(filename, NULL, NULL, NULL, NULL, filename);  		html("<br/>");  	} diff --git a/ui-shared.h b/ui-shared.h index 166246d..9ebc1f9 100644 --- a/ui-shared.h +++ b/ui-shared.h @@ -3,6 +3,7 @@  extern char *cgit_httpscheme();  extern char *cgit_hosturl(); +extern char *cgit_rooturl();  extern char *cgit_repourl(const char *reponame);  extern char *cgit_fileurl(const char *reponame, const char *pagename,  			  const char *filename, const char *query); @@ -30,6 +30,14 @@ static void print_tag_content(char *buf)  	}  } +void print_download_links(char *revname) +{ +	html("<tr><th>download</th><td class='sha1'>"); +	cgit_print_snapshot_links(ctx.qry.repo, ctx.qry.head, +				  revname, ctx.repo->snapshots); +	html("</td></tr>"); +} +  void cgit_print_tag(char *revname)  {  	unsigned char sha1[20]; @@ -56,16 +64,16 @@ void cgit_print_tag(char *revname)  			return;  		}  		html("<table class='commit-info'>\n"); -		htmlf("<tr><td>Tag name</td><td>"); +		htmlf("<tr><td>tag name</td><td>");  		html_txt(revname);  		htmlf(" (%s)</td></tr>\n", sha1_to_hex(sha1));  		if (info->tagger_date > 0) { -			html("<tr><td>Tag date</td><td>"); +			html("<tr><td>tag date</td><td>");  			cgit_print_date(info->tagger_date, FMT_LONGDATE, ctx.cfg.local_time);  			html("</td></tr>\n");  		}  		if (info->tagger) { -			html("<tr><td>Tagged by</td><td>"); +			html("<tr><td>tagged by</td><td>");  			html_txt(info->tagger);  			if (info->tagger_email && !ctx.cfg.noplainemail) {  				html(" "); @@ -73,19 +81,23 @@ void cgit_print_tag(char *revname)  			}  			html("</td></tr>\n");  		} -		html("<tr><td>Tagged object</td><td>"); +		html("<tr><td>tagged object</td><td class='sha1'>");  		cgit_object_link(tag->tagged);  		html("</td></tr>\n"); +		if (ctx.repo->snapshots) +			print_download_links(revname);  		html("</table>\n");  		print_tag_content(info->msg);  	} else {  		html("<table class='commit-info'>\n"); -		htmlf("<tr><td>Tag name</td><td>"); +		htmlf("<tr><td>tag name</td><td>");  		html_txt(revname);  		html("</td></tr>\n"); -		html("<tr><td>Tagged object</td><td>"); +		html("<tr><td>Tagged object</td><td class='sha1'>");  		cgit_object_link(obj);  		html("</td></tr>\n"); +		if (ctx.repo->snapshots) +			print_download_links(revname);  		html("</table>\n");          }  	return; @@ -107,6 +107,12 @@ static void print_object(const unsigned char *sha1, char *path, const char *base  		        curr_rev, path);  	htmlf(")<br/>blob: %s\n", sha1_to_hex(sha1)); +	if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) { +		htmlf("<div class='error'>blob size (%dKB) exceeds display size limit (%dKB).</div>", +				size / 1024, ctx.cfg.max_blob_size); +		return; +	} +  	if (buffer_is_binary(buf, size))  		print_binary_buffer(buf, size);  	else | 
