summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c4
-rw-r--r--cgit.h2
-rw-r--r--cgitrc.5.txt9
-rw-r--r--ui-shared.c28
4 files changed, 37 insertions, 6 deletions
diff --git a/cgit.c b/cgit.c
index 513ea12..2039ab1 100644
--- a/cgit.c
+++ b/cgit.c
@@ -30,70 +30,74 @@ void config_cb(const char *name, const char *value)
30 else if (!strcmp(name, "favicon")) 30 else if (!strcmp(name, "favicon"))
31 ctx.cfg.favicon = xstrdup(value); 31 ctx.cfg.favicon = xstrdup(value);
32 else if (!strcmp(name, "footer")) 32 else if (!strcmp(name, "footer"))
33 ctx.cfg.footer = xstrdup(value); 33 ctx.cfg.footer = xstrdup(value);
34 else if (!strcmp(name, "head-include")) 34 else if (!strcmp(name, "head-include"))
35 ctx.cfg.head_include = xstrdup(value); 35 ctx.cfg.head_include = xstrdup(value);
36 else if (!strcmp(name, "header")) 36 else if (!strcmp(name, "header"))
37 ctx.cfg.header = xstrdup(value); 37 ctx.cfg.header = xstrdup(value);
38 else if (!strcmp(name, "logo")) 38 else if (!strcmp(name, "logo"))
39 ctx.cfg.logo = xstrdup(value); 39 ctx.cfg.logo = xstrdup(value);
40 else if (!strcmp(name, "index-header")) 40 else if (!strcmp(name, "index-header"))
41 ctx.cfg.index_header = xstrdup(value); 41 ctx.cfg.index_header = xstrdup(value);
42 else if (!strcmp(name, "index-info")) 42 else if (!strcmp(name, "index-info"))
43 ctx.cfg.index_info = xstrdup(value); 43 ctx.cfg.index_info = xstrdup(value);
44 else if (!strcmp(name, "logo-link")) 44 else if (!strcmp(name, "logo-link"))
45 ctx.cfg.logo_link = xstrdup(value); 45 ctx.cfg.logo_link = xstrdup(value);
46 else if (!strcmp(name, "module-link")) 46 else if (!strcmp(name, "module-link"))
47 ctx.cfg.module_link = xstrdup(value); 47 ctx.cfg.module_link = xstrdup(value);
48 else if (!strcmp(name, "virtual-root")) { 48 else if (!strcmp(name, "virtual-root")) {
49 ctx.cfg.virtual_root = trim_end(value, '/'); 49 ctx.cfg.virtual_root = trim_end(value, '/');
50 if (!ctx.cfg.virtual_root && (!strcmp(value, "/"))) 50 if (!ctx.cfg.virtual_root && (!strcmp(value, "/")))
51 ctx.cfg.virtual_root = ""; 51 ctx.cfg.virtual_root = "";
52 } else if (!strcmp(name, "nocache")) 52 } else if (!strcmp(name, "nocache"))
53 ctx.cfg.nocache = atoi(value); 53 ctx.cfg.nocache = atoi(value);
54 else if (!strcmp(name, "noheader"))
55 ctx.cfg.noheader = atoi(value);
54 else if (!strcmp(name, "snapshots")) 56 else if (!strcmp(name, "snapshots"))
55 ctx.cfg.snapshots = cgit_parse_snapshots_mask(value); 57 ctx.cfg.snapshots = cgit_parse_snapshots_mask(value);
56 else if (!strcmp(name, "enable-index-links")) 58 else if (!strcmp(name, "enable-index-links"))
57 ctx.cfg.enable_index_links = atoi(value); 59 ctx.cfg.enable_index_links = atoi(value);
58 else if (!strcmp(name, "enable-log-filecount")) 60 else if (!strcmp(name, "enable-log-filecount"))
59 ctx.cfg.enable_log_filecount = atoi(value); 61 ctx.cfg.enable_log_filecount = atoi(value);
60 else if (!strcmp(name, "enable-log-linecount")) 62 else if (!strcmp(name, "enable-log-linecount"))
61 ctx.cfg.enable_log_linecount = atoi(value); 63 ctx.cfg.enable_log_linecount = atoi(value);
62 else if (!strcmp(name, "max-stats")) 64 else if (!strcmp(name, "max-stats"))
63 ctx.cfg.max_stats = cgit_find_stats_period(value, NULL); 65 ctx.cfg.max_stats = cgit_find_stats_period(value, NULL);
64 else if (!strcmp(name, "cache-size")) 66 else if (!strcmp(name, "cache-size"))
65 ctx.cfg.cache_size = atoi(value); 67 ctx.cfg.cache_size = atoi(value);
66 else if (!strcmp(name, "cache-root")) 68 else if (!strcmp(name, "cache-root"))
67 ctx.cfg.cache_root = xstrdup(value); 69 ctx.cfg.cache_root = xstrdup(value);
68 else if (!strcmp(name, "cache-root-ttl")) 70 else if (!strcmp(name, "cache-root-ttl"))
69 ctx.cfg.cache_root_ttl = atoi(value); 71 ctx.cfg.cache_root_ttl = atoi(value);
70 else if (!strcmp(name, "cache-repo-ttl")) 72 else if (!strcmp(name, "cache-repo-ttl"))
71 ctx.cfg.cache_repo_ttl = atoi(value); 73 ctx.cfg.cache_repo_ttl = atoi(value);
72 else if (!strcmp(name, "cache-static-ttl")) 74 else if (!strcmp(name, "cache-static-ttl"))
73 ctx.cfg.cache_static_ttl = atoi(value); 75 ctx.cfg.cache_static_ttl = atoi(value);
74 else if (!strcmp(name, "cache-dynamic-ttl")) 76 else if (!strcmp(name, "cache-dynamic-ttl"))
75 ctx.cfg.cache_dynamic_ttl = atoi(value); 77 ctx.cfg.cache_dynamic_ttl = atoi(value);
78 else if (!strcmp(name, "embedded"))
79 ctx.cfg.embedded = atoi(value);
76 else if (!strcmp(name, "max-message-length")) 80 else if (!strcmp(name, "max-message-length"))
77 ctx.cfg.max_msg_len = atoi(value); 81 ctx.cfg.max_msg_len = atoi(value);
78 else if (!strcmp(name, "max-repodesc-length")) 82 else if (!strcmp(name, "max-repodesc-length"))
79 ctx.cfg.max_repodesc_len = atoi(value); 83 ctx.cfg.max_repodesc_len = atoi(value);
80 else if (!strcmp(name, "max-repo-count")) 84 else if (!strcmp(name, "max-repo-count"))
81 ctx.cfg.max_repo_count = atoi(value); 85 ctx.cfg.max_repo_count = atoi(value);
82 else if (!strcmp(name, "max-commit-count")) 86 else if (!strcmp(name, "max-commit-count"))
83 ctx.cfg.max_commit_count = atoi(value); 87 ctx.cfg.max_commit_count = atoi(value);
84 else if (!strcmp(name, "summary-log")) 88 else if (!strcmp(name, "summary-log"))
85 ctx.cfg.summary_log = atoi(value); 89 ctx.cfg.summary_log = atoi(value);
86 else if (!strcmp(name, "summary-branches")) 90 else if (!strcmp(name, "summary-branches"))
87 ctx.cfg.summary_branches = atoi(value); 91 ctx.cfg.summary_branches = atoi(value);
88 else if (!strcmp(name, "summary-tags")) 92 else if (!strcmp(name, "summary-tags"))
89 ctx.cfg.summary_tags = atoi(value); 93 ctx.cfg.summary_tags = atoi(value);
90 else if (!strcmp(name, "agefile")) 94 else if (!strcmp(name, "agefile"))
91 ctx.cfg.agefile = xstrdup(value); 95 ctx.cfg.agefile = xstrdup(value);
92 else if (!strcmp(name, "renamelimit")) 96 else if (!strcmp(name, "renamelimit"))
93 ctx.cfg.renamelimit = atoi(value); 97 ctx.cfg.renamelimit = atoi(value);
94 else if (!strcmp(name, "robots")) 98 else if (!strcmp(name, "robots"))
95 ctx.cfg.robots = xstrdup(value); 99 ctx.cfg.robots = xstrdup(value);
96 else if (!strcmp(name, "clone-prefix")) 100 else if (!strcmp(name, "clone-prefix"))
97 ctx.cfg.clone_prefix = xstrdup(value); 101 ctx.cfg.clone_prefix = xstrdup(value);
98 else if (!strcmp(name, "local-time")) 102 else if (!strcmp(name, "local-time"))
99 ctx.cfg.local_time = atoi(value); 103 ctx.cfg.local_time = atoi(value);
diff --git a/cgit.h b/cgit.h
index 78b30ba..8c64efe 100644
--- a/cgit.h
+++ b/cgit.h
@@ -135,59 +135,61 @@ struct cgit_config {
135 char *clone_prefix; 135 char *clone_prefix;
136 char *css; 136 char *css;
137 char *favicon; 137 char *favicon;
138 char *footer; 138 char *footer;
139 char *head_include; 139 char *head_include;
140 char *header; 140 char *header;
141 char *index_header; 141 char *index_header;
142 char *index_info; 142 char *index_info;
143 char *logo; 143 char *logo;
144 char *logo_link; 144 char *logo_link;
145 char *module_link; 145 char *module_link;
146 char *repo_group; 146 char *repo_group;
147 char *robots; 147 char *robots;
148 char *root_title; 148 char *root_title;
149 char *root_desc; 149 char *root_desc;
150 char *root_readme; 150 char *root_readme;
151 char *script_name; 151 char *script_name;
152 char *virtual_root; 152 char *virtual_root;
153 int cache_size; 153 int cache_size;
154 int cache_dynamic_ttl; 154 int cache_dynamic_ttl;
155 int cache_max_create_time; 155 int cache_max_create_time;
156 int cache_repo_ttl; 156 int cache_repo_ttl;
157 int cache_root_ttl; 157 int cache_root_ttl;
158 int cache_static_ttl; 158 int cache_static_ttl;
159 int embedded;
159 int enable_index_links; 160 int enable_index_links;
160 int enable_log_filecount; 161 int enable_log_filecount;
161 int enable_log_linecount; 162 int enable_log_linecount;
162 int local_time; 163 int local_time;
163 int max_repo_count; 164 int max_repo_count;
164 int max_commit_count; 165 int max_commit_count;
165 int max_lock_attempts; 166 int max_lock_attempts;
166 int max_msg_len; 167 int max_msg_len;
167 int max_repodesc_len; 168 int max_repodesc_len;
168 int max_stats; 169 int max_stats;
169 int nocache; 170 int nocache;
171 int noheader;
170 int renamelimit; 172 int renamelimit;
171 int snapshots; 173 int snapshots;
172 int summary_branches; 174 int summary_branches;
173 int summary_log; 175 int summary_log;
174 int summary_tags; 176 int summary_tags;
175}; 177};
176 178
177struct cgit_page { 179struct cgit_page {
178 time_t modified; 180 time_t modified;
179 time_t expires; 181 time_t expires;
180 size_t size; 182 size_t size;
181 char *mimetype; 183 char *mimetype;
182 char *charset; 184 char *charset;
183 char *filename; 185 char *filename;
184 char *etag; 186 char *etag;
185 char *title; 187 char *title;
186 int status; 188 int status;
187 char *statusmsg; 189 char *statusmsg;
188}; 190};
189 191
190struct cgit_context { 192struct cgit_context {
191 struct cgit_query qry; 193 struct cgit_query qry;
192 struct cgit_config cfg; 194 struct cgit_config cfg;
193 struct cgit_repo *repo; 195 struct cgit_repo *repo;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 683f3b5..a207fe0 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -38,48 +38,53 @@ cache-repo-ttl::
38 38
39cache-root-ttl:: 39cache-root-ttl::
40 Number which specifies the time-to-live, in minutes, for the cached 40 Number which specifies the time-to-live, in minutes, for the cached
41 version of the repository index page. Default value: "5". 41 version of the repository index page. Default value: "5".
42 42
43cache-size:: 43cache-size::
44 The maximum number of entries in the cgit cache. Default value: "0" 44 The maximum number of entries in the cgit cache. Default value: "0"
45 (i.e. caching is disabled). 45 (i.e. caching is disabled).
46 46
47cache-static-ttl:: 47cache-static-ttl::
48 Number which specifies the time-to-live, in minutes, for the cached 48 Number which specifies the time-to-live, in minutes, for the cached
49 version of repository pages accessed with a fixed SHA1. Default value: 49 version of repository pages accessed with a fixed SHA1. Default value:
50 "5". 50 "5".
51 51
52clone-prefix:: 52clone-prefix::
53 Space-separated list of common prefixes which, when combined with a 53 Space-separated list of common prefixes which, when combined with a
54 repository url, generates valid clone urls for the repository. This 54 repository url, generates valid clone urls for the repository. This
55 setting is only used if `repo.clone-url` is unspecified. Default value: 55 setting is only used if `repo.clone-url` is unspecified. Default value:
56 none. 56 none.
57 57
58css:: 58css::
59 Url which specifies the css document to include in all cgit pages. 59 Url which specifies the css document to include in all cgit pages.
60 Default value: "/cgit.css". 60 Default value: "/cgit.css".
61 61
62embedded::
63 Flag which, when set to "1", will make cgit generate a html fragment
64 suitable for embedding in other html pages. Default value: none. See
65 also: "noheader".
66
62enable-index-links:: 67enable-index-links::
63 Flag which, when set to "1", will make cgit generate extra links for 68 Flag which, when set to "1", will make cgit generate extra links for
64 each repo in the repository index (specifically, to the "summary", 69 each repo in the repository index (specifically, to the "summary",
65 "commit" and "tree" pages). Default value: "0". 70 "commit" and "tree" pages). Default value: "0".
66 71
67enable-log-filecount:: 72enable-log-filecount::
68 Flag which, when set to "1", will make cgit print the number of 73 Flag which, when set to "1", will make cgit print the number of
69 modified files for each commit on the repository log page. Default 74 modified files for each commit on the repository log page. Default
70 value: "0". 75 value: "0".
71 76
72enable-log-linecount:: 77enable-log-linecount::
73 Flag which, when set to "1", will make cgit print the number of added 78 Flag which, when set to "1", will make cgit print the number of added
74 and removed lines for each commit on the repository log page. Default 79 and removed lines for each commit on the repository log page. Default
75 value: "0". 80 value: "0".
76 81
77favicon:: 82favicon::
78 Url used as link to a shortcut icon for cgit. If specified, it is 83 Url used as link to a shortcut icon for cgit. If specified, it is
79 suggested to use the value "/favicon.ico" since certain browsers will 84 suggested to use the value "/favicon.ico" since certain browsers will
80 ignore other values. Default value: none. 85 ignore other values. Default value: none.
81 86
82footer:: 87footer::
83 The content of the file specified with this option will be included 88 The content of the file specified with this option will be included
84 verbatim at the bottom of all pages (i.e. it replaces the standard 89 verbatim at the bottom of all pages (i.e. it replaces the standard
85 "generated by..." message. Default value: none. 90 "generated by..." message. Default value: none.
@@ -132,48 +137,52 @@ max-message-length::
132max-repo-count:: 137max-repo-count::
133 Specifies the number of entries to list per page on therepository 138 Specifies the number of entries to list per page on therepository
134 index page. Default value: "50". 139 index page. Default value: "50".
135 140
136max-repodesc-length:: 141max-repodesc-length::
137 Specifies the maximum number of repo description characters to display 142 Specifies the maximum number of repo description characters to display
138 on the repository index page. Default value: "80". 143 on the repository index page. Default value: "80".
139 144
140max-stats:: 145max-stats::
141 Set the default maximum statistics period. Valid values are "week", 146 Set the default maximum statistics period. Valid values are "week",
142 "month", "quarter" and "year". If unspecified, statistics are 147 "month", "quarter" and "year". If unspecified, statistics are
143 disabled. Default value: none. See also: "repo.max-stats". 148 disabled. Default value: none. See also: "repo.max-stats".
144 149
145module-link:: 150module-link::
146 Text which will be used as the formatstring for a hyperlink when a 151 Text which will be used as the formatstring for a hyperlink when a
147 submodule is printed in a directory listing. The arguments for the 152 submodule is printed in a directory listing. The arguments for the
148 formatstring are the path and SHA1 of the submodule commit. Default 153 formatstring are the path and SHA1 of the submodule commit. Default
149 value: "./?repo=%s&page=commit&id=%s" 154 value: "./?repo=%s&page=commit&id=%s"
150 155
151nocache:: 156nocache::
152 If set to the value "1" caching will be disabled. This settings is 157 If set to the value "1" caching will be disabled. This settings is
153 deprecated, and will not be honored starting with cgit-1.0. Default 158 deprecated, and will not be honored starting with cgit-1.0. Default
154 value: "0". 159 value: "0".
155 160
161noheader::
162 Flag which, when set to "1", will make cgit omit the standard header
163 on all pages. Default value: none. See also: "embedded".
164
156renamelimit:: 165renamelimit::
157 Maximum number of files to consider when detecting renames. The value 166 Maximum number of files to consider when detecting renames. The value
158 "-1" uses the compiletime value in git (for further info, look at 167 "-1" uses the compiletime value in git (for further info, look at
159 `man git-diff`). Default value: "-1". 168 `man git-diff`). Default value: "-1".
160 169
161repo.group:: 170repo.group::
162 A value for the current repository group, which all repositories 171 A value for the current repository group, which all repositories
163 specified after this setting will inherit. Default value: none. 172 specified after this setting will inherit. Default value: none.
164 173
165robots:: 174robots::
166 Text used as content for the "robots" meta-tag. Default value: 175 Text used as content for the "robots" meta-tag. Default value:
167 "index, nofollow". 176 "index, nofollow".
168 177
169root-desc:: 178root-desc::
170 Text printed below the heading on the repository index page. Default 179 Text printed below the heading on the repository index page. Default
171 value: "a fast webinterface for the git dscm". 180 value: "a fast webinterface for the git dscm".
172 181
173root-readme:: 182root-readme::
174 The content of the file specified with this option will be included 183 The content of the file specified with this option will be included
175 verbatim below the "about" link on the repository index page. Default 184 verbatim below the "about" link on the repository index page. Default
176 value: none. 185 value: none.
177 186
178root-title:: 187root-title::
179 Text printed as heading on the repository index page. Default value: 188 Text printed as heading on the repository index page. Default value:
diff --git a/ui-shared.c b/ui-shared.c
index 66d5b82..015c52b 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -448,116 +448,125 @@ void cgit_print_age(time_t t, time_t max_relative, char *format)
448 } 448 }
449 if (secs < TM_WEEK * 2) { 449 if (secs < TM_WEEK * 2) {
450 htmlf("<span class='age-days'>%.0f days</span>", 450 htmlf("<span class='age-days'>%.0f days</span>",
451 secs * 1.0 / TM_DAY); 451 secs * 1.0 / TM_DAY);
452 return; 452 return;
453 } 453 }
454 if (secs < TM_MONTH * 2) { 454 if (secs < TM_MONTH * 2) {
455 htmlf("<span class='age-weeks'>%.0f weeks</span>", 455 htmlf("<span class='age-weeks'>%.0f weeks</span>",
456 secs * 1.0 / TM_WEEK); 456 secs * 1.0 / TM_WEEK);
457 return; 457 return;
458 } 458 }
459 if (secs < TM_YEAR * 2) { 459 if (secs < TM_YEAR * 2) {
460 htmlf("<span class='age-months'>%.0f months</span>", 460 htmlf("<span class='age-months'>%.0f months</span>",
461 secs * 1.0 / TM_MONTH); 461 secs * 1.0 / TM_MONTH);
462 return; 462 return;
463 } 463 }
464 htmlf("<span class='age-years'>%.0f years</span>", 464 htmlf("<span class='age-years'>%.0f years</span>",
465 secs * 1.0 / TM_YEAR); 465 secs * 1.0 / TM_YEAR);
466} 466}
467 467
468void cgit_print_http_headers(struct cgit_context *ctx) 468void cgit_print_http_headers(struct cgit_context *ctx)
469{ 469{
470 const char *method = getenv("REQUEST_METHOD"); 470 const char *method = getenv("REQUEST_METHOD");
471 471
472 if (ctx->cfg.embedded)
473 return;
474
472 if (ctx->page.status) 475 if (ctx->page.status)
473 htmlf("Status: %d %s\n", ctx->page.status, ctx->page.statusmsg); 476 htmlf("Status: %d %s\n", ctx->page.status, ctx->page.statusmsg);
474 if (ctx->page.mimetype && ctx->page.charset) 477 if (ctx->page.mimetype && ctx->page.charset)
475 htmlf("Content-Type: %s; charset=%s\n", ctx->page.mimetype, 478 htmlf("Content-Type: %s; charset=%s\n", ctx->page.mimetype,
476 ctx->page.charset); 479 ctx->page.charset);
477 else if (ctx->page.mimetype) 480 else if (ctx->page.mimetype)
478 htmlf("Content-Type: %s\n", ctx->page.mimetype); 481 htmlf("Content-Type: %s\n", ctx->page.mimetype);
479 if (ctx->page.size) 482 if (ctx->page.size)
480 htmlf("Content-Length: %ld\n", ctx->page.size); 483 htmlf("Content-Length: %ld\n", ctx->page.size);
481 if (ctx->page.filename) 484 if (ctx->page.filename)
482 htmlf("Content-Disposition: inline; filename=\"%s\"\n", 485 htmlf("Content-Disposition: inline; filename=\"%s\"\n",
483 ctx->page.filename); 486 ctx->page.filename);
484 htmlf("Last-Modified: %s\n", http_date(ctx->page.modified)); 487 htmlf("Last-Modified: %s\n", http_date(ctx->page.modified));
485 htmlf("Expires: %s\n", http_date(ctx->page.expires)); 488 htmlf("Expires: %s\n", http_date(ctx->page.expires));
486 if (ctx->page.etag) 489 if (ctx->page.etag)
487 htmlf("ETag: \"%s\"\n", ctx->page.etag); 490 htmlf("ETag: \"%s\"\n", ctx->page.etag);
488 html("\n"); 491 html("\n");
489 if (method && !strcmp(method, "HEAD")) 492 if (method && !strcmp(method, "HEAD"))
490 exit(0); 493 exit(0);
491} 494}
492 495
493void cgit_print_docstart(struct cgit_context *ctx) 496void cgit_print_docstart(struct cgit_context *ctx)
494{ 497{
498 if (ctx->cfg.embedded)
499 return;
500
495 char *host = cgit_hosturl(); 501 char *host = cgit_hosturl();
496 html(cgit_doctype); 502 html(cgit_doctype);
497 html("<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>\n"); 503 html("<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>\n");
498 html("<head>\n"); 504 html("<head>\n");
499 html("<title>"); 505 html("<title>");
500 html_txt(ctx->page.title); 506 html_txt(ctx->page.title);
501 html("</title>\n"); 507 html("</title>\n");
502 htmlf("<meta name='generator' content='cgit %s'/>\n", cgit_version); 508 htmlf("<meta name='generator' content='cgit %s'/>\n", cgit_version);
503 if (ctx->cfg.robots && *ctx->cfg.robots) 509 if (ctx->cfg.robots && *ctx->cfg.robots)
504 htmlf("<meta name='robots' content='%s'/>\n", ctx->cfg.robots); 510 htmlf("<meta name='robots' content='%s'/>\n", ctx->cfg.robots);
505 html("<link rel='stylesheet' type='text/css' href='"); 511 html("<link rel='stylesheet' type='text/css' href='");
506 html_attr(ctx->cfg.css); 512 html_attr(ctx->cfg.css);
507 html("'/>\n"); 513 html("'/>\n");
508 if (ctx->cfg.favicon) { 514 if (ctx->cfg.favicon) {
509 html("<link rel='shortcut icon' href='"); 515 html("<link rel='shortcut icon' href='");
510 html_attr(ctx->cfg.favicon); 516 html_attr(ctx->cfg.favicon);
511 html("'/>\n"); 517 html("'/>\n");
512 } 518 }
513 if (host && ctx->repo) { 519 if (host && ctx->repo) {
514 html("<link rel='alternate' title='Atom feed' href='"); 520 html("<link rel='alternate' title='Atom feed' href='");
515 html(cgit_httpscheme()); 521 html(cgit_httpscheme());
516 html_attr(cgit_hosturl()); 522 html_attr(cgit_hosturl());
517 html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.path, 523 html_attr(cgit_fileurl(ctx->repo->url, "atom", ctx->qry.path,
518 fmt("h=%s", ctx->qry.head))); 524 fmt("h=%s", ctx->qry.head)));
519 html("' type='application/atom+xml'/>\n"); 525 html("' type='application/atom+xml'/>\n");
520 } 526 }
521 if (ctx->cfg.head_include) 527 if (ctx->cfg.head_include)
522 html_include(ctx->cfg.head_include); 528 html_include(ctx->cfg.head_include);
523 html("</head>\n"); 529 html("</head>\n");
524 html("<body>\n"); 530 html("<body>\n");
525 if (ctx->cfg.header) 531 if (ctx->cfg.header)
526 html_include(ctx->cfg.header); 532 html_include(ctx->cfg.header);
527} 533}
528 534
529void cgit_print_docend() 535void cgit_print_docend()
530{ 536{
531 html("</div>"); 537 html("</div>");
532 if (ctx.cfg.footer) 538 if (ctx.cfg.footer)
533 html_include(ctx.cfg.footer); 539 html_include(ctx.cfg.footer);
534 else { 540 else {
535 htmlf("<div class='footer'>generated by cgit %s at ", 541 htmlf("<div class='footer'>generated by cgit %s at ",
536 cgit_version); 542 cgit_version);
537 cgit_print_date(time(NULL), FMT_LONGDATE, ctx.cfg.local_time); 543 cgit_print_date(time(NULL), FMT_LONGDATE, ctx.cfg.local_time);
538 html("</div>\n"); 544 html("</div>\n");
539 } 545 }
546 html("</div>");
547 if (ctx.cfg.embedded)
548 return;
540 html("</body>\n</html>\n"); 549 html("</body>\n</html>\n");
541} 550}
542 551
543int print_branch_option(const char *refname, const unsigned char *sha1, 552int print_branch_option(const char *refname, const unsigned char *sha1,
544 int flags, void *cb_data) 553 int flags, void *cb_data)
545{ 554{
546 char *name = (char *)refname; 555 char *name = (char *)refname;
547 html_option(name, name, ctx.qry.head); 556 html_option(name, name, ctx.qry.head);
548 return 0; 557 return 0;
549} 558}
550 559
551int print_archive_ref(const char *refname, const unsigned char *sha1, 560int print_archive_ref(const char *refname, const unsigned char *sha1,
552 int flags, void *cb_data) 561 int flags, void *cb_data)
553{ 562{
554 struct tag *tag; 563 struct tag *tag;
555 struct taginfo *info; 564 struct taginfo *info;
556 struct object *obj; 565 struct object *obj;
557 char buf[256], *url; 566 char buf[256], *url;
558 unsigned char fileid[20]; 567 unsigned char fileid[20];
559 int *header = (int *)cb_data; 568 int *header = (int *)cb_data;
560 569
561 if (prefixcmp(refname, "refs/archives")) 570 if (prefixcmp(refname, "refs/archives"))
562 return 0; 571 return 0;
563 strncpy(buf, refname+14, sizeof(buf)); 572 strncpy(buf, refname+14, sizeof(buf));
@@ -603,95 +612,102 @@ void cgit_add_hidden_formfields(int incl_head, int incl_search, char *page)
603 html_hidden("h", ctx.qry.head); 612 html_hidden("h", ctx.qry.head);
604 613
605 if (ctx.qry.sha1) 614 if (ctx.qry.sha1)
606 html_hidden("id", ctx.qry.sha1); 615 html_hidden("id", ctx.qry.sha1);
607 if (ctx.qry.sha2) 616 if (ctx.qry.sha2)
608 html_hidden("id2", ctx.qry.sha2); 617 html_hidden("id2", ctx.qry.sha2);
609 if (ctx.qry.showmsg) 618 if (ctx.qry.showmsg)
610 html_hidden("showmsg", "1"); 619 html_hidden("showmsg", "1");
611 620
612 if (incl_search) { 621 if (incl_search) {
613 if (ctx.qry.grep) 622 if (ctx.qry.grep)
614 html_hidden("qt", ctx.qry.grep); 623 html_hidden("qt", ctx.qry.grep);
615 if (ctx.qry.search) 624 if (ctx.qry.search)
616 html_hidden("q", ctx.qry.search); 625 html_hidden("q", ctx.qry.search);
617 } 626 }
618} 627}
619 628
620const char *fallback_cmd = "repolist"; 629const char *fallback_cmd = "repolist";
621 630
622char *hc(struct cgit_cmd *cmd, const char *page) 631char *hc(struct cgit_cmd *cmd, const char *page)
623{ 632{
624 return (strcmp(cmd ? cmd->name : fallback_cmd, page) ? NULL : "active"); 633 return (strcmp(cmd ? cmd->name : fallback_cmd, page) ? NULL : "active");
625} 634}
626 635
627void cgit_print_pageheader(struct cgit_context *ctx) 636static void print_header(struct cgit_context *ctx)
628{ 637{
629 struct cgit_cmd *cmd = cgit_get_cmd(ctx);
630
631 if (!cmd && ctx->repo)
632 fallback_cmd = "summary";
633
634 html("<table id='header'>\n"); 638 html("<table id='header'>\n");
635 html("<tr>\n"); 639 html("<tr>\n");
636 html("<td class='logo' rowspan='2'><a href='"); 640 html("<td class='logo' rowspan='2'><a href='");
637 if (ctx->cfg.logo_link) 641 if (ctx->cfg.logo_link)
638 html_attr(ctx->cfg.logo_link); 642 html_attr(ctx->cfg.logo_link);
639 else 643 else
640 html_attr(cgit_rooturl()); 644 html_attr(cgit_rooturl());
641 html("'><img src='"); 645 html("'><img src='");
642 html_attr(ctx->cfg.logo); 646 html_attr(ctx->cfg.logo);
643 html("' alt='cgit logo'/></a></td>\n"); 647 html("' alt='cgit logo'/></a></td>\n");
644 648
645 html("<td class='main'>"); 649 html("<td class='main'>");
646 if (ctx->repo) { 650 if (ctx->repo) {
647 cgit_index_link("index", NULL, NULL, NULL, 0); 651 cgit_index_link("index", NULL, NULL, NULL, 0);
648 html(" : "); 652 html(" : ");
649 cgit_summary_link(ctx->repo->name, ctx->repo->name, NULL, NULL); 653 cgit_summary_link(ctx->repo->name, ctx->repo->name, NULL, NULL);
650 html("</td><td class='form'>"); 654 html("</td><td class='form'>");
651 html("<form method='get' action=''>\n"); 655 html("<form method='get' action=''>\n");
652 cgit_add_hidden_formfields(0, 1, ctx->qry.page); 656 cgit_add_hidden_formfields(0, 1, ctx->qry.page);
653 html("<select name='h' onchange='this.form.submit();'>\n"); 657 html("<select name='h' onchange='this.form.submit();'>\n");
654 for_each_branch_ref(print_branch_option, ctx->qry.head); 658 for_each_branch_ref(print_branch_option, ctx->qry.head);
655 html("</select> "); 659 html("</select> ");
656 html("<input type='submit' name='' value='switch'/>"); 660 html("<input type='submit' name='' value='switch'/>");
657 html("</form>"); 661 html("</form>");
658 } else 662 } else
659 html_txt(ctx->cfg.root_title); 663 html_txt(ctx->cfg.root_title);
660 html("</td></tr>\n"); 664 html("</td></tr>\n");
661 665
662 html("<tr><td class='sub'>"); 666 html("<tr><td class='sub'>");
663 if (ctx->repo) { 667 if (ctx->repo) {
664 html_txt(ctx->repo->desc); 668 html_txt(ctx->repo->desc);
665 html("</td><td class='sub right'>"); 669 html("</td><td class='sub right'>");
666 html_txt(ctx->repo->owner); 670 html_txt(ctx->repo->owner);
667 } else { 671 } else {
668 if (ctx->cfg.root_desc) 672 if (ctx->cfg.root_desc)
669 html_txt(ctx->cfg.root_desc); 673 html_txt(ctx->cfg.root_desc);
670 else if (ctx->cfg.index_info) 674 else if (ctx->cfg.index_info)
671 html_include(ctx->cfg.index_info); 675 html_include(ctx->cfg.index_info);
672 } 676 }
673 html("</td></tr></table>\n"); 677 html("</td></tr></table>\n");
678}
679
680void cgit_print_pageheader(struct cgit_context *ctx)
681{
682 struct cgit_cmd *cmd = cgit_get_cmd(ctx);
683
684 if (!cmd && ctx->repo)
685 fallback_cmd = "summary";
686
687 html("<div id='cgit'>");
688 if (!ctx->cfg.noheader)
689 print_header(ctx);
674 690
675 html("<table class='tabs'><tr><td>\n"); 691 html("<table class='tabs'><tr><td>\n");
676 if (ctx->repo) { 692 if (ctx->repo) {
677 cgit_summary_link("summary", NULL, hc(cmd, "summary"), 693 cgit_summary_link("summary", NULL, hc(cmd, "summary"),
678 ctx->qry.head); 694 ctx->qry.head);
679 cgit_refs_link("refs", NULL, hc(cmd, "refs"), ctx->qry.head, 695 cgit_refs_link("refs", NULL, hc(cmd, "refs"), ctx->qry.head,
680 ctx->qry.sha1, NULL); 696 ctx->qry.sha1, NULL);
681 cgit_log_link("log", NULL, hc(cmd, "log"), ctx->qry.head, 697 cgit_log_link("log", NULL, hc(cmd, "log"), ctx->qry.head,
682 NULL, NULL, 0, NULL, NULL, ctx->qry.showmsg); 698 NULL, NULL, 0, NULL, NULL, ctx->qry.showmsg);
683 cgit_tree_link("tree", NULL, hc(cmd, "tree"), ctx->qry.head, 699 cgit_tree_link("tree", NULL, hc(cmd, "tree"), ctx->qry.head,
684 ctx->qry.sha1, NULL); 700 ctx->qry.sha1, NULL);
685 cgit_commit_link("commit", NULL, hc(cmd, "commit"), 701 cgit_commit_link("commit", NULL, hc(cmd, "commit"),
686 ctx->qry.head, ctx->qry.sha1); 702 ctx->qry.head, ctx->qry.sha1);
687 cgit_diff_link("diff", NULL, hc(cmd, "diff"), ctx->qry.head, 703 cgit_diff_link("diff", NULL, hc(cmd, "diff"), ctx->qry.head,
688 ctx->qry.sha1, ctx->qry.sha2, NULL); 704 ctx->qry.sha1, ctx->qry.sha2, NULL);
689 if (ctx->repo->max_stats) 705 if (ctx->repo->max_stats)
690 cgit_stats_link("stats", NULL, hc(cmd, "stats"), 706 cgit_stats_link("stats", NULL, hc(cmd, "stats"),
691 ctx->qry.head, NULL); 707 ctx->qry.head, NULL);
692 if (ctx->repo->readme) 708 if (ctx->repo->readme)
693 reporevlink("about", "about", NULL, 709 reporevlink("about", "about", NULL,
694 hc(cmd, "about"), ctx->qry.head, NULL, 710 hc(cmd, "about"), ctx->qry.head, NULL,
695 NULL); 711 NULL);
696 html("</td><td class='form'>"); 712 html("</td><td class='form'>");
697 html("<form class='right' method='get' action='"); 713 html("<form class='right' method='get' action='");