-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | Makefile | 21 | ||||
-rw-r--r-- | cgit-doc.css | 3 | ||||
-rw-r--r-- | cgit.c | 8 | ||||
-rw-r--r-- | cgit.h | 4 | ||||
-rw-r--r-- | cgitrc.5.txt | 122 | ||||
-rw-r--r-- | ui-atom.c | 6 | ||||
-rw-r--r-- | ui-blob.c | 8 | ||||
-rw-r--r-- | ui-plain.c | 6 | ||||
-rw-r--r-- | ui-shared.c | 26 | ||||
-rw-r--r-- | ui-shared.h | 1 | ||||
-rw-r--r-- | ui-snapshot.c | 23 | ||||
-rw-r--r-- | ui-tree.c | 26 |
13 files changed, 177 insertions, 82 deletions
@@ -4,2 +4,7 @@ cgit.conf VERSION +cgitrc.5 +cgitrc.5.fo +cgitrc.5.html +cgitrc.5.pdf +cgitrc.5.xml *.o @@ -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; +} @@ -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) @@ -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 +.... @@ -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); @@ -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; @@ -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; @@ -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"); |