summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--.gitignore5
-rw-r--r--Makefile21
-rw-r--r--cgit-doc.css3
-rw-r--r--cgit.c8
-rw-r--r--cgit.h4
-rw-r--r--cgitrc.5.txt122
-rw-r--r--ui-atom.c6
-rw-r--r--ui-blob.c8
-rw-r--r--ui-plain.c6
-rw-r--r--ui-shared.c26
-rw-r--r--ui-shared.h1
-rw-r--r--ui-snapshot.c23
-rw-r--r--ui-tree.c26
13 files changed, 177 insertions, 82 deletions
diff --git a/.gitignore b/.gitignore
index 1e016e5..487728b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,2 +4,7 @@ cgit.conf
VERSION
+cgitrc.5
+cgitrc.5.fo
+cgitrc.5.html
+cgitrc.5.pdf
+cgitrc.5.xml
*.o
diff --git a/Makefile b/Makefile
index 0f0089a..707d446 100644
--- a/Makefile
+++ b/Makefile
@@ -1,2 +1,2 @@
-CGIT_VERSION = v0.8.2
+CGIT_VERSION = v0.8.2.1
CGIT_SCRIPT_NAME = cgit.cgi
@@ -102,3 +102,4 @@ endif
-.PHONY: all libgit test install uninstall clean force-version get-git
+.PHONY: all libgit test install uninstall clean force-version get-git \
+ doc man-doc html-doc clean-doc
@@ -151,5 +152,19 @@ uninstall:
-clean:
+doc: man-doc html-doc pdf-doc
+
+man-doc: cgitrc.5.txt
+ a2x -f manpage cgitrc.5.txt
+
+html-doc: cgitrc.5.txt
+ a2x -f xhtml --stylesheet=cgit-doc.css cgitrc.5.txt
+
+pdf-doc: cgitrc.5.txt
+ a2x -f pdf cgitrc.5.txt
+
+clean: clean-doc
rm -f cgit VERSION *.o *.d
+clean-doc:
+ rm -f cgitrc.5 cgitrc.5.html cgitrc.5.pdf cgitrc.5.xml cgitrc.5.fo
+
get-git:
diff --git a/cgit-doc.css b/cgit-doc.css
new file mode 100644
index 0000000..5a399b6
--- a/dev/null
+++ b/cgit-doc.css
@@ -0,0 +1,3 @@
+div.variablelist dt {
+ margin-top: 1em;
+}
diff --git a/cgit.c b/cgit.c
index 38f0fdd..2039ab1 100644
--- a/cgit.c
+++ b/cgit.c
@@ -33,2 +33,4 @@ void config_cb(const char *name, const char *value)
ctx.cfg.footer = xstrdup(value);
+ else if (!strcmp(name, "head-include"))
+ ctx.cfg.head_include = xstrdup(value);
else if (!strcmp(name, "header"))
@@ -212,2 +214,3 @@ static void prepare_context(struct cgit_context *ctx)
ctx->page.expires = ctx->page.modified;
+ ctx->page.etag = NULL;
}
@@ -291,2 +294,4 @@ static int prepare_repo_cmd(struct cgit_context *ctx)
ctx->qry.head = ctx->repo->defbranch;
+ ctx->page.status = 404;
+ ctx->page.statusmsg = "not found";
cgit_print_http_headers(ctx);
@@ -435,2 +440,3 @@ int main(int argc, const char **argv)
const char *cgit_config_env = getenv("CGIT_CONFIG");
+ const char *method = getenv("REQUEST_METHOD");
const char *path;
@@ -481,2 +487,4 @@ int main(int argc, const char **argv)
ctx.page.expires += ttl*60;
+ if (method && !strcmp(method, "HEAD"))
+ ctx.cfg.nocache = 1;
if (ctx.cfg.nocache)
diff --git a/cgit.h b/cgit.h
index ca01705..8c64efe 100644
--- a/cgit.h
+++ b/cgit.h
@@ -138,2 +138,3 @@ struct cgit_config {
char *footer;
+ char *head_include;
char *header;
@@ -184,3 +185,6 @@ struct cgit_page {
char *filename;
+ char *etag;
char *title;
+ int status;
+ char *statusmsg;
};
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 771bb7d..a207fe0 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -1,3 +1,3 @@
-CGITRC
-======
+CGITRC(5)
+========
@@ -6,7 +6,7 @@ NAME
----
- cgitrc - runtime configuration for cgit
+cgitrc - runtime configuration for cgit
-DESCRIPTION
------------
+SYNOPSIS
+--------
Cgitrc contains all runtime settings for cgit, including the list of git
@@ -18,3 +18,3 @@ GLOBAL SETTINGS
---------------
-agefile
+agefile::
Specifies a path, relative to each repository path, which can be used
@@ -25,3 +25,3 @@ agefile
-cache-root
+cache-root::
Path used to store the cgit cache entries. Default value:
@@ -29,3 +29,3 @@ cache-root
-cache-dynamic-ttl
+cache-dynamic-ttl::
Number which specifies the time-to-live, in minutes, for the cached
@@ -34,3 +34,3 @@ cache-dynamic-ttl
-cache-repo-ttl
+cache-repo-ttl::
Number which specifies the time-to-live, in minutes, for the cached
@@ -38,3 +38,3 @@ cache-repo-ttl
-cache-root-ttl
+cache-root-ttl::
Number which specifies the time-to-live, in minutes, for the cached
@@ -42,3 +42,3 @@ cache-root-ttl
-cache-size
+cache-size::
The maximum number of entries in the cgit cache. Default value: "0"
@@ -46,3 +46,3 @@ cache-size
-cache-static-ttl
+cache-static-ttl::
Number which specifies the time-to-live, in minutes, for the cached
@@ -51,3 +51,3 @@ cache-static-ttl
-clone-prefix
+clone-prefix::
Space-separated list of common prefixes which, when combined with a
@@ -57,3 +57,3 @@ clone-prefix
-css
+css::
Url which specifies the css document to include in all cgit pages.
@@ -61,3 +61,3 @@ css
-embedded
+embedded::
Flag which, when set to "1", will make cgit generate a html fragment
@@ -66,3 +66,3 @@ embedded
-enable-index-links
+enable-index-links::
Flag which, when set to "1", will make cgit generate extra links for
@@ -71,3 +71,3 @@ enable-index-links
-enable-log-filecount
+enable-log-filecount::
Flag which, when set to "1", will make cgit print the number of
@@ -76,3 +76,3 @@ enable-log-filecount
-enable-log-linecount
+enable-log-linecount::
Flag which, when set to "1", will make cgit print the number of added
@@ -81,3 +81,3 @@ enable-log-linecount
-favicon
+favicon::
Url used as link to a shortcut icon for cgit. If specified, it is
@@ -86,3 +86,3 @@ favicon
-footer
+footer::
The content of the file specified with this option will be included
@@ -91,3 +91,7 @@ footer
-header
+head-include::
+ The content of the file specified with this option will be included
+ verbatim in the html HEAD section on all pages. Default value: none.
+
+header::
The content of the file specified with this option will be included
@@ -95,3 +99,3 @@ header
-include
+include::
Name of a configfile to include before the rest of the current config-
@@ -99,3 +103,3 @@ include
-index-header
+index-header::
The content of the file specified with this option will be included
@@ -105,3 +109,3 @@ index-header
-index-info
+index-info::
The content of the file specified with this option will be included
@@ -111,3 +115,3 @@ index-info
-local-time
+local-time::
Flag which, if set to "1", makes cgit print commit and tag times in the
@@ -115,3 +119,3 @@ local-time
-logo
+logo::
Url which specifies the source of an image which will be used as a logo
@@ -119,3 +123,3 @@ logo
-logo-link
+logo-link::
Url loaded when clicking on the cgit logo image. If unspecified the
@@ -124,3 +128,3 @@ logo-link
-max-commit-count
+max-commit-count::
Specifies the number of entries to list per page in "log" view. Default
@@ -128,3 +132,3 @@ max-commit-count
-max-message-length
+max-message-length::
Specifies the maximum number of commit message characters to display in
@@ -132,3 +136,3 @@ max-message-length
-max-repo-count
+max-repo-count::
Specifies the number of entries to list per page on the repository
@@ -136,3 +140,3 @@ max-repo-count
-max-repodesc-length
+max-repodesc-length::
Specifies the maximum number of repo description characters to display
@@ -140,3 +144,3 @@ max-repodesc-length
-max-stats
+max-stats::
Set the default maximum statistics period. Valid values are "week",
@@ -145,3 +149,3 @@ max-stats
-module-link
+module-link::
Text which will be used as the formatstring for a hyperlink when a
@@ -151,3 +155,3 @@ module-link
-nocache
+nocache::
If set to the value "1" caching will be disabled. This settings is
@@ -156,3 +160,3 @@ nocache
-noheader
+noheader::
Flag which, when set to "1", will make cgit omit the standard header
@@ -160,3 +164,3 @@ noheader
-renamelimit
+renamelimit::
Maximum number of files to consider when detecting renames. The value
@@ -165,3 +169,3 @@ renamelimit
-repo.group
+repo.group::
A value for the current repository group, which all repositories
@@ -169,3 +173,3 @@ repo.group
-robots
+robots::
Text used as content for the "robots" meta-tag. Default value:
@@ -173,3 +177,3 @@ robots
-root-desc
+root-desc::
Text printed below the heading on the repository index page. Default
@@ -177,3 +181,3 @@ root-desc
-root-readme:
+root-readme::
The content of the file specified with this option will be included
@@ -182,3 +186,3 @@ root-readme:
-root-title
+root-title::
Text printed as heading on the repository index page. Default value:
@@ -186,3 +190,3 @@ root-title
-snapshots
+snapshots::
Text which specifies the default (and allowed) set of snapshot formats
@@ -196,3 +200,3 @@ snapshots
-summary-branches
+summary-branches::
Specifies the number of branches to display in the repository "summary"
@@ -200,3 +204,3 @@ summary-branches
-summary-log
+summary-log::
Specifies the number of log entries to display in the repository
@@ -204,3 +208,3 @@ summary-log
-summary-tags
+summary-tags::
Specifies the number of tags to display in the repository "summary"
@@ -208,3 +212,3 @@ summary-tags
-virtual-root
+virtual-root::
Url which, if specified, will be used as root for all cgit links. It
@@ -218,3 +222,3 @@ REPOSITORY SETTINGS
-------------------
-repo.clone-url
+repo.clone-url::
A list of space-separated urls which can be used to clone this repo.
@@ -222,3 +226,3 @@ repo.clone-url
-repo.defbranch
+repo.defbranch::
The name of the default branch for this repository. If no such branch
@@ -227,6 +231,6 @@ repo.defbranch
-repo.desc
+repo.desc::
The value to show as repository description. Default value: none.
-repo.enable-log-filecount
+repo.enable-log-filecount::
A flag which can be used to disable the global setting
@@ -234,3 +238,3 @@ repo.enable-log-filecount
-repo.enable-log-linecount
+repo.enable-log-linecount::
A flag which can be used to disable the global setting
@@ -238,3 +242,3 @@ repo.enable-log-linecount
-repo.max-stats
+repo.max-stats::
Override the default maximum statistics period. Valid values are equal
@@ -243,6 +247,6 @@ repo.max-stats
-repo.name
+repo.name::
The value to show as repository name. Default value: <repo.url>.
-repo.owner
+repo.owner::
A value used to identify the owner of the repository. Default value:
@@ -250,3 +254,3 @@ repo.owner
-repo.path
+repo.path::
An absolute path to the repository directory. For non-bare repositories
@@ -254,3 +258,3 @@ repo.path
-repo.readme
+repo.readme::
A path (relative to <repo.path>) which specifies a file to include
@@ -258,3 +262,3 @@ repo.readme
-repo.snapshots
+repo.snapshots::
A mask of allowed snapshot-formats for this repo, restricted by the
@@ -262,3 +266,3 @@ repo.snapshots
-repo.url
+repo.url::
The relative url used to access the repository. This must be the first
@@ -270,2 +274,3 @@ EXAMPLE CGITRC FILE
+....
# Enable caching of up to 1000 output entriess
@@ -379,2 +384,3 @@ repo.enable-log-linecount=0
repo.max-stats=month
+....
diff --git a/ui-atom.c b/ui-atom.c
index a6ea3ee..e5c31d9 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -54,3 +54,4 @@ void add_entry(struct commit *commit, char *host)
if (host) {
- html("<link rel='alternate' type='text/html' href='http://");
+ html("<link rel='alternate' type='text/html' href='");
+ html(cgit_httpscheme());
html_attr(host);
@@ -115,3 +116,4 @@ void cgit_print_atom(char *tip, char *path, int max_count)
if (host) {
- html("<link rel='alternate' type='text/html' href='http://");
+ html("<link rel='alternate' type='text/html' href='");
+ html(cgit_httpscheme());
html_attr(host);
diff --git a/ui-blob.c b/ui-blob.c
index 3cda03d..2ccd31d 100644
--- a/ui-blob.c
+++ b/ui-blob.c
@@ -29,3 +29,3 @@ void cgit_print_blob(const char *hex, char *path, const char *head)
enum object_type type;
- unsigned char *buf;
+ char *buf;
unsigned long size;
@@ -69,2 +69,8 @@ void cgit_print_blob(const char *hex, char *path, const char *head)
ctx.page.mimetype = ctx.qry.mimetype;
+ if (!ctx.page.mimetype) {
+ if (buffer_is_binary(buf, size))
+ ctx.page.mimetype = "application/octet-stream";
+ else
+ ctx.page.mimetype = "text/plain";
+ }
ctx.page.filename = path;
diff --git a/ui-plain.c b/ui-plain.c
index 5addd9e..93a3a05 100644
--- a/ui-plain.c
+++ b/ui-plain.c
@@ -33,5 +33,9 @@ static void print_object(const unsigned char *sha1, const char *path)
}
- ctx.page.mimetype = "text/plain";
+ if (buffer_is_binary(buf, size))
+ ctx.page.mimetype = "application/octet-stream";
+ else
+ ctx.page.mimetype = "text/plain";
ctx.page.filename = fmt("%s", path);
ctx.page.size = size;
+ ctx.page.etag = sha1_to_hex(sha1);
cgit_print_http_headers(&ctx);
diff --git a/ui-shared.c b/ui-shared.c
index 5e03a7a..015c52b 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -36,2 +36,13 @@ void cgit_print_error(char *msg)
+char *cgit_httpscheme()
+{
+ char *https;
+
+ https = getenv("HTTPS");
+ if (https != NULL && strcmp(https, "on") == 0)
+ return "https://";
+ else
+ return "http://";
+}
+
char *cgit_hosturl()
@@ -458,2 +469,4 @@ void cgit_print_http_headers(struct cgit_context *ctx)
{
+ const char *method = getenv("REQUEST_METHOD");
+
if (ctx->cfg.embedded)
@@ -461,2 +474,4 @@ void cgit_print_http_headers(struct cgit_context *ctx)
+ if (ctx->page.status)
+ htmlf("Status: %d %s\n", ctx->page.status, ctx->page.statusmsg);
if (ctx->page.mimetype && ctx->page.charset)
@@ -473,3 +488,7 @@ void cgit_print_http_headers(struct cgit_context *ctx)
htmlf("Expires: %s\n", http_date(ctx->page.expires));
+ if (ctx->page.etag)
+ htmlf("ETag: \"%s\"\n", ctx->page.etag);
html("\n");
+ if (method && !strcmp(method, "HEAD"))
+ exit(0);
}
@@ -500,3 +519,4 @@ void cgit_print_docstart(struct cgit_context *ctx)
if (host && ctx->repo) {
- html("<link rel='alternate' title='Atom feed' href='http://");
+ html("<link rel='alternate' title='Atom feed' href='");
+ html(cgit_httpscheme());
html_attr(cgit_hosturl());
@@ -504,4 +524,6 @@ void cgit_print_docstart(struct cgit_context *ctx)
fmt("h=%s", ctx->qry.head)));
- html("' type='application/atom+xml'/>");
+ html("' type='application/atom+xml'/>\n");
}
+ if (ctx->cfg.head_include)
+ html_include(ctx->cfg.head_include);
html("</head>\n");
diff --git a/ui-shared.h b/ui-shared.h
index 5a3821f..bff4826 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -3,2 +3,3 @@
+extern char *cgit_httpscheme();
extern char *cgit_hosturl();
diff --git a/ui-snapshot.c b/ui-snapshot.c
index f25613e..5372f5d 100644
--- a/ui-snapshot.c
+++ b/ui-snapshot.c
@@ -158,2 +158,12 @@ static const char *get_ref_from_filename(const char *url, const char *filename,
+void show_error(char *msg)
+{
+ ctx.page.mimetype = "text/html";
+ cgit_print_http_headers(&ctx);
+ cgit_print_docstart(&ctx);
+ cgit_print_pageheader(&ctx);
+ cgit_print_error(msg);
+ cgit_print_docend();
+}
+
void cgit_print_snapshot(const char *head, const char *hex,
@@ -164,10 +174,11 @@ void cgit_print_snapshot(const char *head, const char *hex,
+ if (!filename) {
+ show_error("No snapshot name specified");
+ return;
+ }
+
f = get_format(filename);
if (!f) {
- ctx.page.mimetype = "text/html";
- cgit_print_http_headers(&ctx);
- cgit_print_docstart(&ctx);
- cgit_print_pageheader(&ctx);
- cgit_print_error(fmt("Unsupported snapshot format: %s", filename));
- cgit_print_docend();
+ show_error(xstrdup(fmt("Unsupported snapshot format: %s",
+ filename)));
return;
diff --git a/ui-tree.c b/ui-tree.c
index a37a4e5..553dbaa 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -27,7 +27,10 @@ static void print_text_buffer(char *buf, unsigned long size)
lineno = 0;
- htmlf(numberfmt, ++lineno);
- while(idx < size - 1) { // skip absolute last newline
- if (buf[idx] == '\n')
- htmlf(numberfmt, ++lineno);
- idx++;
+
+ if (size) {
+ htmlf(numberfmt, ++lineno);
+ while(idx < size - 1) { // skip absolute last newline
+ if (buf[idx] == '\n')
+ htmlf(numberfmt, ++lineno);
+ idx++;
+ }
}
@@ -39,2 +42,4 @@ static void print_text_buffer(char *buf, unsigned long size)
+#define ROWLEN 32
+
static void print_binary_buffer(char *buf, unsigned long size)
@@ -42,2 +47,3 @@ static void print_binary_buffer(char *buf, unsigned long size)
unsigned long ofs, idx;
+ static char ascii[ROWLEN + 1];
@@ -45,5 +51,5 @@ static void print_binary_buffer(char *buf, unsigned long size)
html("<tr><th>ofs</th><th>hex dump</th><th>ascii</th></tr>");
- for (ofs = 0; ofs < size; ofs += 32, buf += 32) {
+ for (ofs = 0; ofs < size; ofs += ROWLEN, buf += ROWLEN) {
htmlf("<tr><td class='right'>%04x</td><td class='hex'>", ofs);
- for (idx = 0; idx < 32 && ofs + idx < size; idx++)
+ for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++)
htmlf("%*s%02x",
@@ -52,4 +58,6 @@ static void print_binary_buffer(char *buf, unsigned long size)
html(" </td><td class='hex'>");
- for (idx = 0; idx < 32 && ofs + idx < size; idx++)
- htmlf("%c", isgraph(buf[idx]) ? buf[idx] : '.');
+ for (idx = 0; idx < ROWLEN && ofs + idx < size; idx++)
+ ascii[idx] = isgraph(buf[idx]) ? buf[idx] : '.';
+ ascii[idx] = '\0';
+ html_txt(ascii);
html("</td></tr>\n");