summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--cgit.c4
-rw-r--r--cgit.css2
-rw-r--r--cgit.h4
-rw-r--r--cgitrc.5.txt9
-rw-r--r--shared.c2
-rw-r--r--ui-repolist.c18
6 files changed, 22 insertions, 17 deletions
diff --git a/cgit.c b/cgit.c
index a792fe4..013a0fe 100644
--- a/cgit.c
+++ b/cgit.c
@@ -114,66 +114,66 @@ void config_cb(const char *name, const char *value)
114 ctx.cfg.max_msg_len = atoi(value); 114 ctx.cfg.max_msg_len = atoi(value);
115 else if (!strcmp(name, "max-repodesc-length")) 115 else if (!strcmp(name, "max-repodesc-length"))
116 ctx.cfg.max_repodesc_len = atoi(value); 116 ctx.cfg.max_repodesc_len = atoi(value);
117 else if (!strcmp(name, "max-repo-count")) 117 else if (!strcmp(name, "max-repo-count"))
118 ctx.cfg.max_repo_count = atoi(value); 118 ctx.cfg.max_repo_count = atoi(value);
119 else if (!strcmp(name, "max-commit-count")) 119 else if (!strcmp(name, "max-commit-count"))
120 ctx.cfg.max_commit_count = atoi(value); 120 ctx.cfg.max_commit_count = atoi(value);
121 else if (!strcmp(name, "scan-path")) 121 else if (!strcmp(name, "scan-path"))
122 if (!ctx.cfg.nocache && ctx.cfg.cache_size) 122 if (!ctx.cfg.nocache && ctx.cfg.cache_size)
123 process_cached_repolist(value); 123 process_cached_repolist(value);
124 else 124 else
125 scan_tree(value); 125 scan_tree(value);
126 else if (!strcmp(name, "source-filter")) 126 else if (!strcmp(name, "source-filter"))
127 ctx.cfg.source_filter = new_filter(value, 1); 127 ctx.cfg.source_filter = new_filter(value, 1);
128 else if (!strcmp(name, "summary-log")) 128 else if (!strcmp(name, "summary-log"))
129 ctx.cfg.summary_log = atoi(value); 129 ctx.cfg.summary_log = atoi(value);
130 else if (!strcmp(name, "summary-branches")) 130 else if (!strcmp(name, "summary-branches"))
131 ctx.cfg.summary_branches = atoi(value); 131 ctx.cfg.summary_branches = atoi(value);
132 else if (!strcmp(name, "summary-tags")) 132 else if (!strcmp(name, "summary-tags"))
133 ctx.cfg.summary_tags = atoi(value); 133 ctx.cfg.summary_tags = atoi(value);
134 else if (!strcmp(name, "agefile")) 134 else if (!strcmp(name, "agefile"))
135 ctx.cfg.agefile = xstrdup(value); 135 ctx.cfg.agefile = xstrdup(value);
136 else if (!strcmp(name, "renamelimit")) 136 else if (!strcmp(name, "renamelimit"))
137 ctx.cfg.renamelimit = atoi(value); 137 ctx.cfg.renamelimit = atoi(value);
138 else if (!strcmp(name, "robots")) 138 else if (!strcmp(name, "robots"))
139 ctx.cfg.robots = xstrdup(value); 139 ctx.cfg.robots = xstrdup(value);
140 else if (!strcmp(name, "clone-prefix")) 140 else if (!strcmp(name, "clone-prefix"))
141 ctx.cfg.clone_prefix = xstrdup(value); 141 ctx.cfg.clone_prefix = xstrdup(value);
142 else if (!strcmp(name, "local-time")) 142 else if (!strcmp(name, "local-time"))
143 ctx.cfg.local_time = atoi(value); 143 ctx.cfg.local_time = atoi(value);
144 else if (!prefixcmp(name, "mimetype.")) 144 else if (!prefixcmp(name, "mimetype."))
145 add_mimetype(name + 9, value); 145 add_mimetype(name + 9, value);
146 else if (!strcmp(name, "repo.group")) 146 else if (!strcmp(name, "section") || !strcmp(name, "repo.group"))
147 ctx.cfg.repo_group = xstrdup(value); 147 ctx.cfg.section = xstrdup(value);
148 else if (!strcmp(name, "repo.url")) 148 else if (!strcmp(name, "repo.url"))
149 ctx.repo = cgit_add_repo(value); 149 ctx.repo = cgit_add_repo(value);
150 else if (!strcmp(name, "repo.name")) 150 else if (!strcmp(name, "repo.name"))
151 ctx.repo->name = xstrdup(value); 151 ctx.repo->name = xstrdup(value);
152 else if (ctx.repo && !strcmp(name, "repo.path")) 152 else if (ctx.repo && !strcmp(name, "repo.path"))
153 ctx.repo->path = trim_end(value, '/'); 153 ctx.repo->path = trim_end(value, '/');
154 else if (ctx.repo && !strcmp(name, "repo.clone-url")) 154 else if (ctx.repo && !strcmp(name, "repo.clone-url"))
155 ctx.repo->clone_url = xstrdup(value); 155 ctx.repo->clone_url = xstrdup(value);
156 else if (ctx.repo && !strcmp(name, "repo.desc")) 156 else if (ctx.repo && !strcmp(name, "repo.desc"))
157 ctx.repo->desc = xstrdup(value); 157 ctx.repo->desc = xstrdup(value);
158 else if (ctx.repo && !strcmp(name, "repo.owner")) 158 else if (ctx.repo && !strcmp(name, "repo.owner"))
159 ctx.repo->owner = xstrdup(value); 159 ctx.repo->owner = xstrdup(value);
160 else if (ctx.repo && !strcmp(name, "repo.defbranch")) 160 else if (ctx.repo && !strcmp(name, "repo.defbranch"))
161 ctx.repo->defbranch = xstrdup(value); 161 ctx.repo->defbranch = xstrdup(value);
162 else if (ctx.repo && !strcmp(name, "repo.snapshots")) 162 else if (ctx.repo && !strcmp(name, "repo.snapshots"))
163 ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */ 163 ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */
164 else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount")) 164 else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount"))
165 ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); 165 ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value);
166 else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount")) 166 else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount"))
167 ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); 167 ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value);
168 else if (ctx.repo && !strcmp(name, "repo.max-stats")) 168 else if (ctx.repo && !strcmp(name, "repo.max-stats"))
169 ctx.repo->max_stats = cgit_find_stats_period(value, NULL); 169 ctx.repo->max_stats = cgit_find_stats_period(value, NULL);
170 else if (ctx.repo && !strcmp(name, "repo.module-link")) 170 else if (ctx.repo && !strcmp(name, "repo.module-link"))
171 ctx.repo->module_link= xstrdup(value); 171 ctx.repo->module_link= xstrdup(value);
172 else if (ctx.repo && !strcmp(name, "repo.about-filter")) 172 else if (ctx.repo && !strcmp(name, "repo.about-filter"))
173 ctx.repo->about_filter = new_filter(value, 0); 173 ctx.repo->about_filter = new_filter(value, 0);
174 else if (ctx.repo && !strcmp(name, "repo.commit-filter")) 174 else if (ctx.repo && !strcmp(name, "repo.commit-filter"))
175 ctx.repo->commit_filter = new_filter(value, 0); 175 ctx.repo->commit_filter = new_filter(value, 0);
176 else if (ctx.repo && !strcmp(name, "repo.source-filter")) 176 else if (ctx.repo && !strcmp(name, "repo.source-filter"))
177 ctx.repo->source_filter = new_filter(value, 1); 177 ctx.repo->source_filter = new_filter(value, 1);
178 else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) { 178 else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) {
179 if (*value == '/') 179 if (*value == '/')
diff --git a/cgit.css b/cgit.css
index e3b32e7..3c65114 100644
--- a/cgit.css
+++ b/cgit.css
@@ -400,65 +400,65 @@ table.diff td {
400 400
401table.diff td div.head { 401table.diff td div.head {
402 font-weight: bold; 402 font-weight: bold;
403 margin-top: 1em; 403 margin-top: 1em;
404 color: black; 404 color: black;
405} 405}
406 406
407table.diff td div.hunk { 407table.diff td div.hunk {
408 color: #009; 408 color: #009;
409} 409}
410 410
411table.diff td div.add { 411table.diff td div.add {
412 color: green; 412 color: green;
413} 413}
414 414
415table.diff td div.del { 415table.diff td div.del {
416 color: red; 416 color: red;
417} 417}
418 418
419.sha1 { 419.sha1 {
420 font-family: monospace; 420 font-family: monospace;
421 font-size: 90%; 421 font-size: 90%;
422} 422}
423 423
424.left { 424.left {
425 text-align: left; 425 text-align: left;
426} 426}
427 427
428.right { 428.right {
429 text-align: right; 429 text-align: right;
430} 430}
431 431
432table.list td.repogroup { 432table.list td.reposection {
433 font-style: italic; 433 font-style: italic;
434 color: #888; 434 color: #888;
435} 435}
436 436
437a.button { 437a.button {
438 font-size: 80%; 438 font-size: 80%;
439 padding: 0em 0.5em; 439 padding: 0em 0.5em;
440} 440}
441 441
442a.primary { 442a.primary {
443 font-size: 100%; 443 font-size: 100%;
444} 444}
445 445
446a.secondary { 446a.secondary {
447 font-size: 90%; 447 font-size: 90%;
448} 448}
449 449
450td.toplevel-repo { 450td.toplevel-repo {
451 451
452} 452}
453 453
454table.list td.sublevel-repo { 454table.list td.sublevel-repo {
455 padding-left: 1.5em; 455 padding-left: 1.5em;
456} 456}
457 457
458div.pager { 458div.pager {
459 text-align: center; 459 text-align: center;
460 margin: 1em 0em 0em 0em; 460 margin: 1em 0em 0em 0em;
461} 461}
462 462
463div.pager a { 463div.pager a {
464 color: #777; 464 color: #777;
diff --git a/cgit.h b/cgit.h
index 5659580..fc7c7d5 100644
--- a/cgit.h
+++ b/cgit.h
@@ -36,67 +36,67 @@
36#define TM_HOUR (TM_MIN * 60) 36#define TM_HOUR (TM_MIN * 60)
37#define TM_DAY (TM_HOUR * 24) 37#define TM_DAY (TM_HOUR * 24)
38#define TM_WEEK (TM_DAY * 7) 38#define TM_WEEK (TM_DAY * 7)
39#define TM_YEAR (TM_DAY * 365) 39#define TM_YEAR (TM_DAY * 365)
40#define TM_MONTH (TM_YEAR / 12.0) 40#define TM_MONTH (TM_YEAR / 12.0)
41 41
42 42
43/* 43/*
44 * Default encoding 44 * Default encoding
45 */ 45 */
46#define PAGE_ENCODING "UTF-8" 46#define PAGE_ENCODING "UTF-8"
47 47
48typedef void (*configfn)(const char *name, const char *value); 48typedef void (*configfn)(const char *name, const char *value);
49typedef void (*filepair_fn)(struct diff_filepair *pair); 49typedef void (*filepair_fn)(struct diff_filepair *pair);
50typedef void (*linediff_fn)(char *line, int len); 50typedef void (*linediff_fn)(char *line, int len);
51 51
52struct cgit_filter { 52struct cgit_filter {
53 char *cmd; 53 char *cmd;
54 char **argv; 54 char **argv;
55 int old_stdout; 55 int old_stdout;
56 int pipe_fh[2]; 56 int pipe_fh[2];
57 int pid; 57 int pid;
58 int exitstatus; 58 int exitstatus;
59}; 59};
60 60
61struct cgit_repo { 61struct cgit_repo {
62 char *url; 62 char *url;
63 char *name; 63 char *name;
64 char *path; 64 char *path;
65 char *desc; 65 char *desc;
66 char *owner; 66 char *owner;
67 char *defbranch; 67 char *defbranch;
68 char *group;
69 char *module_link; 68 char *module_link;
70 char *readme; 69 char *readme;
70 char *section;
71 char *clone_url; 71 char *clone_url;
72 int snapshots; 72 int snapshots;
73 int enable_log_filecount; 73 int enable_log_filecount;
74 int enable_log_linecount; 74 int enable_log_linecount;
75 int max_stats; 75 int max_stats;
76 time_t mtime; 76 time_t mtime;
77 struct cgit_filter *about_filter; 77 struct cgit_filter *about_filter;
78 struct cgit_filter *commit_filter; 78 struct cgit_filter *commit_filter;
79 struct cgit_filter *source_filter; 79 struct cgit_filter *source_filter;
80}; 80};
81 81
82struct cgit_repolist { 82struct cgit_repolist {
83 int length; 83 int length;
84 int count; 84 int count;
85 struct cgit_repo *repos; 85 struct cgit_repo *repos;
86}; 86};
87 87
88struct commitinfo { 88struct commitinfo {
89 struct commit *commit; 89 struct commit *commit;
90 char *author; 90 char *author;
91 char *author_email; 91 char *author_email;
92 unsigned long author_date; 92 unsigned long author_date;
93 char *committer; 93 char *committer;
94 char *committer_email; 94 char *committer_email;
95 unsigned long committer_date; 95 unsigned long committer_date;
96 char *subject; 96 char *subject;
97 char *msg; 97 char *msg;
98 char *msg_encoding; 98 char *msg_encoding;
99}; 99};
100 100
101struct taginfo { 101struct taginfo {
102 char *tagger; 102 char *tagger;
@@ -127,70 +127,70 @@ struct cgit_query {
127 char *repo; 127 char *repo;
128 char *page; 128 char *page;
129 char *search; 129 char *search;
130 char *grep; 130 char *grep;
131 char *head; 131 char *head;
132 char *sha1; 132 char *sha1;
133 char *sha2; 133 char *sha2;
134 char *path; 134 char *path;
135 char *name; 135 char *name;
136 char *mimetype; 136 char *mimetype;
137 char *url; 137 char *url;
138 char *period; 138 char *period;
139 int ofs; 139 int ofs;
140 int nohead; 140 int nohead;
141 char *sort; 141 char *sort;
142 int showmsg; 142 int showmsg;
143}; 143};
144 144
145struct cgit_config { 145struct cgit_config {
146 char *agefile; 146 char *agefile;
147 char *cache_root; 147 char *cache_root;
148 char *clone_prefix; 148 char *clone_prefix;
149 char *css; 149 char *css;
150 char *favicon; 150 char *favicon;
151 char *footer; 151 char *footer;
152 char *head_include; 152 char *head_include;
153 char *header; 153 char *header;
154 char *index_header; 154 char *index_header;
155 char *index_info; 155 char *index_info;
156 char *logo; 156 char *logo;
157 char *logo_link; 157 char *logo_link;
158 char *module_link; 158 char *module_link;
159 char *repo_group;
160 char *robots; 159 char *robots;
161 char *root_title; 160 char *root_title;
162 char *root_desc; 161 char *root_desc;
163 char *root_readme; 162 char *root_readme;
164 char *script_name; 163 char *script_name;
164 char *section;
165 char *virtual_root; 165 char *virtual_root;
166 int cache_size; 166 int cache_size;
167 int cache_dynamic_ttl; 167 int cache_dynamic_ttl;
168 int cache_max_create_time; 168 int cache_max_create_time;
169 int cache_repo_ttl; 169 int cache_repo_ttl;
170 int cache_root_ttl; 170 int cache_root_ttl;
171 int cache_scanrc_ttl; 171 int cache_scanrc_ttl;
172 int cache_static_ttl; 172 int cache_static_ttl;
173 int embedded; 173 int embedded;
174 int enable_index_links; 174 int enable_index_links;
175 int enable_log_filecount; 175 int enable_log_filecount;
176 int enable_log_linecount; 176 int enable_log_linecount;
177 int local_time; 177 int local_time;
178 int max_repo_count; 178 int max_repo_count;
179 int max_commit_count; 179 int max_commit_count;
180 int max_lock_attempts; 180 int max_lock_attempts;
181 int max_msg_len; 181 int max_msg_len;
182 int max_repodesc_len; 182 int max_repodesc_len;
183 int max_stats; 183 int max_stats;
184 int nocache; 184 int nocache;
185 int noplainemail; 185 int noplainemail;
186 int noheader; 186 int noheader;
187 int renamelimit; 187 int renamelimit;
188 int snapshots; 188 int snapshots;
189 int summary_branches; 189 int summary_branches;
190 int summary_log; 190 int summary_log;
191 int summary_tags; 191 int summary_tags;
192 struct string_list mimetypes; 192 struct string_list mimetypes;
193 struct cgit_filter *about_filter; 193 struct cgit_filter *about_filter;
194 struct cgit_filter *commit_filter; 194 struct cgit_filter *commit_filter;
195 struct cgit_filter *source_filter; 195 struct cgit_filter *source_filter;
196}; 196};
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 2abbd41..4d009f9 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -171,89 +171,94 @@ max-stats::
171 "month", "quarter" and "year". If unspecified, statistics are 171 "month", "quarter" and "year". If unspecified, statistics are
172 disabled. Default value: none. See also: "repo.max-stats". 172 disabled. Default value: none. See also: "repo.max-stats".
173 173
174mimetype.<ext>:: 174mimetype.<ext>::
175 Set the mimetype for the specified filename extension. This is used 175 Set the mimetype for the specified filename extension. This is used
176 by the `plain` command when returning blob content. 176 by the `plain` command when returning blob content.
177 177
178module-link:: 178module-link::
179 Text which will be used as the formatstring for a hyperlink when a 179 Text which will be used as the formatstring for a hyperlink when a
180 submodule is printed in a directory listing. The arguments for the 180 submodule is printed in a directory listing. The arguments for the
181 formatstring are the path and SHA1 of the submodule commit. Default 181 formatstring are the path and SHA1 of the submodule commit. Default
182 value: "./?repo=%s&page=commit&id=%s" 182 value: "./?repo=%s&page=commit&id=%s"
183 183
184nocache:: 184nocache::
185 If set to the value "1" caching will be disabled. This settings is 185 If set to the value "1" caching will be disabled. This settings is
186 deprecated, and will not be honored starting with cgit-1.0. Default 186 deprecated, and will not be honored starting with cgit-1.0. Default
187 value: "0". 187 value: "0".
188 188
189noplainemail:: 189noplainemail::
190 If set to "1" showing full author email adresses will be disabled. 190 If set to "1" showing full author email adresses will be disabled.
191 Default value: "0". 191 Default value: "0".
192 192
193noheader:: 193noheader::
194 Flag which, when set to "1", will make cgit omit the standard header 194 Flag which, when set to "1", will make cgit omit the standard header
195 on all pages. Default value: none. See also: "embedded". 195 on all pages. Default value: none. See also: "embedded".
196 196
197renamelimit:: 197renamelimit::
198 Maximum number of files to consider when detecting renames. The value 198 Maximum number of files to consider when detecting renames. The value
199 "-1" uses the compiletime value in git (for further info, look at 199 "-1" uses the compiletime value in git (for further info, look at
200 `man git-diff`). Default value: "-1". 200 `man git-diff`). Default value: "-1".
201 201
202repo.group:: 202repo.group::
203 A value for the current repository group, which all repositories 203 Legacy alias for 'section' which will be deprecated starting with
204 specified after this setting will inherit. Default value: none. 204 cgit-1.0.
205 205
206robots:: 206robots::
207 Text used as content for the "robots" meta-tag. Default value: 207 Text used as content for the "robots" meta-tag. Default value:
208 "index, nofollow". 208 "index, nofollow".
209 209
210root-desc:: 210root-desc::
211 Text printed below the heading on the repository index page. Default 211 Text printed below the heading on the repository index page. Default
212 value: "a fast webinterface for the git dscm". 212 value: "a fast webinterface for the git dscm".
213 213
214root-readme:: 214root-readme::
215 The content of the file specified with this option will be included 215 The content of the file specified with this option will be included
216 verbatim below the "about" link on the repository index page. Default 216 verbatim below the "about" link on the repository index page. Default
217 value: none. 217 value: none.
218 218
219root-title:: 219root-title::
220 Text printed as heading on the repository index page. Default value: 220 Text printed as heading on the repository index page. Default value:
221 "Git Repository Browser". 221 "Git Repository Browser".
222 222
223scan-path:: 223scan-path::
224 A path which will be scanned for repositories. If caching is enabled, 224 A path which will be scanned for repositories. If caching is enabled,
225 the result will be cached as a cgitrc include-file in the cache 225 the result will be cached as a cgitrc include-file in the cache
226 directory. Default value: none. See also: cache-scanrc-ttl. 226 directory. Default value: none. See also: cache-scanrc-ttl.
227 227
228section:
229 The name of the current repository section - all repositories defined
230 after this option will inherit the current section name. Default value:
231 none.
232
228snapshots:: 233snapshots::
229 Text which specifies the default set of snapshot formats generated by 234 Text which specifies the default set of snapshot formats generated by
230 cgit. The value is a space-separated list of zero or more of the 235 cgit. The value is a space-separated list of zero or more of the
231 values "tar", "tar.gz", "tar.bz2" and "zip". Default value: none. 236 values "tar", "tar.gz", "tar.bz2" and "zip". Default value: none.
232 237
233source-filter:: 238source-filter::
234 Specifies a command which will be invoked to format plaintext blobs 239 Specifies a command which will be invoked to format plaintext blobs
235 in the tree view. The command will get the blob content on its STDIN 240 in the tree view. The command will get the blob content on its STDIN
236 and the name of the blob as its only command line argument. The STDOUT 241 and the name of the blob as its only command line argument. The STDOUT
237 from the command will be included verbatim as the blob contents, i.e. 242 from the command will be included verbatim as the blob contents, i.e.
238 this can be used to implement e.g. syntax highlighting. Default value: 243 this can be used to implement e.g. syntax highlighting. Default value:
239 none. 244 none.
240 245
241summary-branches:: 246summary-branches::
242 Specifies the number of branches to display in the repository "summary" 247 Specifies the number of branches to display in the repository "summary"
243 view. Default value: "10". 248 view. Default value: "10".
244 249
245summary-log:: 250summary-log::
246 Specifies the number of log entries to display in the repository 251 Specifies the number of log entries to display in the repository
247 "summary" view. Default value: "10". 252 "summary" view. Default value: "10".
248 253
249summary-tags:: 254summary-tags::
250 Specifies the number of tags to display in the repository "summary" 255 Specifies the number of tags to display in the repository "summary"
251 view. Default value: "10". 256 view. Default value: "10".
252 257
253virtual-root:: 258virtual-root::
254 Url which, if specified, will be used as root for all cgit links. It 259 Url which, if specified, will be used as root for all cgit links. It
255 will also cause cgit to generate 'virtual urls', i.e. urls like 260 will also cause cgit to generate 'virtual urls', i.e. urls like
256 '/cgit/tree/README' as opposed to '?r=cgit&p=tree&path=README'. Default 261 '/cgit/tree/README' as opposed to '?r=cgit&p=tree&path=README'. Default
257 value: none. 262 value: none.
258 NOTE: cgit has recently learned how to use PATH_INFO to achieve the 263 NOTE: cgit has recently learned how to use PATH_INFO to achieve the
259 same kind of virtual urls, so this option will probably be deprecated. 264 same kind of virtual urls, so this option will probably be deprecated.
diff --git a/shared.c b/shared.c
index 4cb9573..9475581 100644
--- a/shared.c
+++ b/shared.c
@@ -24,65 +24,65 @@ int chk_positive(int result, char *msg)
24 if (result <= 0) 24 if (result <= 0)
25 die("%s: %s", msg, strerror(errno)); 25 die("%s: %s", msg, strerror(errno));
26 return result; 26 return result;
27} 27}
28 28
29int chk_non_negative(int result, char *msg) 29int chk_non_negative(int result, char *msg)
30{ 30{
31 if (result < 0) 31 if (result < 0)
32 die("%s: %s",msg, strerror(errno)); 32 die("%s: %s",msg, strerror(errno));
33 return result; 33 return result;
34} 34}
35 35
36struct cgit_repo *cgit_add_repo(const char *url) 36struct cgit_repo *cgit_add_repo(const char *url)
37{ 37{
38 struct cgit_repo *ret; 38 struct cgit_repo *ret;
39 39
40 if (++cgit_repolist.count > cgit_repolist.length) { 40 if (++cgit_repolist.count > cgit_repolist.length) {
41 if (cgit_repolist.length == 0) 41 if (cgit_repolist.length == 0)
42 cgit_repolist.length = 8; 42 cgit_repolist.length = 8;
43 else 43 else
44 cgit_repolist.length *= 2; 44 cgit_repolist.length *= 2;
45 cgit_repolist.repos = xrealloc(cgit_repolist.repos, 45 cgit_repolist.repos = xrealloc(cgit_repolist.repos,
46 cgit_repolist.length * 46 cgit_repolist.length *
47 sizeof(struct cgit_repo)); 47 sizeof(struct cgit_repo));
48 } 48 }
49 49
50 ret = &cgit_repolist.repos[cgit_repolist.count-1]; 50 ret = &cgit_repolist.repos[cgit_repolist.count-1];
51 ret->url = trim_end(url, '/'); 51 ret->url = trim_end(url, '/');
52 ret->name = ret->url; 52 ret->name = ret->url;
53 ret->path = NULL; 53 ret->path = NULL;
54 ret->desc = "[no description]"; 54 ret->desc = "[no description]";
55 ret->owner = NULL; 55 ret->owner = NULL;
56 ret->group = ctx.cfg.repo_group; 56 ret->section = ctx.cfg.section;
57 ret->defbranch = "master"; 57 ret->defbranch = "master";
58 ret->snapshots = ctx.cfg.snapshots; 58 ret->snapshots = ctx.cfg.snapshots;
59 ret->enable_log_filecount = ctx.cfg.enable_log_filecount; 59 ret->enable_log_filecount = ctx.cfg.enable_log_filecount;
60 ret->enable_log_linecount = ctx.cfg.enable_log_linecount; 60 ret->enable_log_linecount = ctx.cfg.enable_log_linecount;
61 ret->max_stats = ctx.cfg.max_stats; 61 ret->max_stats = ctx.cfg.max_stats;
62 ret->module_link = ctx.cfg.module_link; 62 ret->module_link = ctx.cfg.module_link;
63 ret->readme = NULL; 63 ret->readme = NULL;
64 ret->mtime = -1; 64 ret->mtime = -1;
65 ret->about_filter = ctx.cfg.about_filter; 65 ret->about_filter = ctx.cfg.about_filter;
66 ret->commit_filter = ctx.cfg.commit_filter; 66 ret->commit_filter = ctx.cfg.commit_filter;
67 ret->source_filter = ctx.cfg.source_filter; 67 ret->source_filter = ctx.cfg.source_filter;
68 return ret; 68 return ret;
69} 69}
70 70
71struct cgit_repo *cgit_get_repoinfo(const char *url) 71struct cgit_repo *cgit_get_repoinfo(const char *url)
72{ 72{
73 int i; 73 int i;
74 struct cgit_repo *repo; 74 struct cgit_repo *repo;
75 75
76 for (i=0; i<cgit_repolist.count; i++) { 76 for (i=0; i<cgit_repolist.count; i++) {
77 repo = &cgit_repolist.repos[i]; 77 repo = &cgit_repolist.repos[i];
78 if (!strcmp(repo->url, url)) 78 if (!strcmp(repo->url, url))
79 return repo; 79 return repo;
80 } 80 }
81 return NULL; 81 return NULL;
82} 82}
83 83
84void *cgit_free_commitinfo(struct commitinfo *info) 84void *cgit_free_commitinfo(struct commitinfo *info)
85{ 85{
86 free(info->author); 86 free(info->author);
87 free(info->author_email); 87 free(info->author_email);
88 free(info->committer); 88 free(info->committer);
diff --git a/ui-repolist.c b/ui-repolist.c
index 7c7aa9b..4dea3b3 100644
--- a/ui-repolist.c
+++ b/ui-repolist.c
@@ -174,106 +174,106 @@ static int sort_idle(const void *a, const void *b)
174 174
175struct sortcolumn { 175struct sortcolumn {
176 const char *name; 176 const char *name;
177 int (*fn)(const void *a, const void *b); 177 int (*fn)(const void *a, const void *b);
178}; 178};
179 179
180struct sortcolumn sortcolumn[] = { 180struct sortcolumn sortcolumn[] = {
181 {"name", sort_name}, 181 {"name", sort_name},
182 {"desc", sort_desc}, 182 {"desc", sort_desc},
183 {"owner", sort_owner}, 183 {"owner", sort_owner},
184 {"idle", sort_idle}, 184 {"idle", sort_idle},
185 {NULL, NULL} 185 {NULL, NULL}
186}; 186};
187 187
188int sort_repolist(char *field) 188int sort_repolist(char *field)
189{ 189{
190 struct sortcolumn *column; 190 struct sortcolumn *column;
191 191
192 for (column = &sortcolumn[0]; column->name; column++) { 192 for (column = &sortcolumn[0]; column->name; column++) {
193 if (strcmp(field, column->name)) 193 if (strcmp(field, column->name))
194 continue; 194 continue;
195 qsort(cgit_repolist.repos, cgit_repolist.count, 195 qsort(cgit_repolist.repos, cgit_repolist.count,
196 sizeof(struct cgit_repo), column->fn); 196 sizeof(struct cgit_repo), column->fn);
197 return 1; 197 return 1;
198 } 198 }
199 return 0; 199 return 0;
200} 200}
201 201
202 202
203void cgit_print_repolist() 203void cgit_print_repolist()
204{ 204{
205 int i, columns = 4, hits = 0, header = 0; 205 int i, columns = 4, hits = 0, header = 0;
206 char *last_group = NULL; 206 char *last_section = NULL;
207 int sorted = 0; 207 int sorted = 0;
208 208
209 if (ctx.cfg.enable_index_links) 209 if (ctx.cfg.enable_index_links)
210 columns++; 210 columns++;
211 211
212 ctx.page.title = ctx.cfg.root_title; 212 ctx.page.title = ctx.cfg.root_title;
213 cgit_print_http_headers(&ctx); 213 cgit_print_http_headers(&ctx);
214 cgit_print_docstart(&ctx); 214 cgit_print_docstart(&ctx);
215 cgit_print_pageheader(&ctx); 215 cgit_print_pageheader(&ctx);
216 216
217 if (ctx.cfg.index_header) 217 if (ctx.cfg.index_header)
218 html_include(ctx.cfg.index_header); 218 html_include(ctx.cfg.index_header);
219 219
220 if(ctx.qry.sort) 220 if(ctx.qry.sort)
221 sorted = sort_repolist(ctx.qry.sort); 221 sorted = sort_repolist(ctx.qry.sort);
222 222
223 html("<table summary='repository list' class='list nowrap'>"); 223 html("<table summary='repository list' class='list nowrap'>");
224 for (i=0; i<cgit_repolist.count; i++) { 224 for (i=0; i<cgit_repolist.count; i++) {
225 ctx.repo = &cgit_repolist.repos[i]; 225 ctx.repo = &cgit_repolist.repos[i];
226 if (!(is_match(ctx.repo) && is_in_url(ctx.repo))) 226 if (!(is_match(ctx.repo) && is_in_url(ctx.repo)))
227 continue; 227 continue;
228 hits++; 228 hits++;
229 if (hits <= ctx.qry.ofs) 229 if (hits <= ctx.qry.ofs)
230 continue; 230 continue;
231 if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count) 231 if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count)
232 continue; 232 continue;
233 if (!header++) 233 if (!header++)
234 print_header(columns); 234 print_header(columns);
235 if (!sorted && 235 if (!sorted &&
236 ((last_group == NULL && ctx.repo->group != NULL) || 236 ((last_section == NULL && ctx.repo->section != NULL) ||
237 (last_group != NULL && ctx.repo->group == NULL) || 237 (last_section != NULL && ctx.repo->section == NULL) ||
238 (last_group != NULL && ctx.repo->group != NULL && 238 (last_section != NULL && ctx.repo->section != NULL &&
239 strcmp(ctx.repo->group, last_group)))) { 239 strcmp(ctx.repo->section, last_section)))) {
240 htmlf("<tr class='nohover'><td colspan='%d' class='repogroup'>", 240 htmlf("<tr class='nohover'><td colspan='%d' class='reposection'>",
241 columns); 241 columns);
242 html_txt(ctx.repo->group); 242 html_txt(ctx.repo->section);
243 html("</td></tr>"); 243 html("</td></tr>");
244 last_group = ctx.repo->group; 244 last_section = ctx.repo->section;
245 } 245 }
246 htmlf("<tr><td class='%s'>", 246 htmlf("<tr><td class='%s'>",
247 !sorted && ctx.repo->group ? "sublevel-repo" : "toplevel-repo"); 247 !sorted && ctx.repo->section ? "sublevel-repo" : "toplevel-repo");
248 cgit_summary_link(ctx.repo->name, ctx.repo->name, NULL, NULL); 248 cgit_summary_link(ctx.repo->name, ctx.repo->name, NULL, NULL);
249 html("</td><td>"); 249 html("</td><td>");
250 html_link_open(cgit_repourl(ctx.repo->url), NULL, NULL); 250 html_link_open(cgit_repourl(ctx.repo->url), NULL, NULL);
251 html_ntxt(ctx.cfg.max_repodesc_len, ctx.repo->desc); 251 html_ntxt(ctx.cfg.max_repodesc_len, ctx.repo->desc);
252 html_link_close(); 252 html_link_close();
253 html("</td><td>"); 253 html("</td><td>");
254 html_txt(ctx.repo->owner); 254 html_txt(ctx.repo->owner);
255 html("</td><td>"); 255 html("</td><td>");
256 print_modtime(ctx.repo); 256 print_modtime(ctx.repo);
257 html("</td>"); 257 html("</td>");
258 if (ctx.cfg.enable_index_links) { 258 if (ctx.cfg.enable_index_links) {
259 html("<td>"); 259 html("<td>");
260 cgit_summary_link("summary", NULL, "button", NULL); 260 cgit_summary_link("summary", NULL, "button", NULL);
261 cgit_log_link("log", NULL, "button", NULL, NULL, NULL, 261 cgit_log_link("log", NULL, "button", NULL, NULL, NULL,
262 0, NULL, NULL, ctx.qry.showmsg); 262 0, NULL, NULL, ctx.qry.showmsg);
263 cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL); 263 cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL);
264 html("</td>"); 264 html("</td>");
265 } 265 }
266 html("</tr>\n"); 266 html("</tr>\n");
267 } 267 }
268 html("</table>"); 268 html("</table>");
269 if (!hits) 269 if (!hits)
270 cgit_print_error("No repositories found"); 270 cgit_print_error("No repositories found");
271 else if (hits > ctx.cfg.max_repo_count) 271 else if (hits > ctx.cfg.max_repo_count)
272 print_pager(hits, ctx.cfg.max_repo_count, ctx.qry.search); 272 print_pager(hits, ctx.cfg.max_repo_count, ctx.qry.search);
273 cgit_print_docend(); 273 cgit_print_docend();
274} 274}
275 275
276void cgit_print_site_readme() 276void cgit_print_site_readme()
277{ 277{
278 if (!ctx.cfg.root_readme) 278 if (!ctx.cfg.root_readme)
279 return; 279 return;