summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.css14
-rw-r--r--cgit.h1
-rw-r--r--cgitrc1
-rw-r--r--shared.c8
-rw-r--r--ui-summary.c14
5 files changed, 23 insertions, 15 deletions
diff --git a/cgit.css b/cgit.css
index 327eaba..8977533 100644
--- a/cgit.css
+++ b/cgit.css
@@ -119,64 +119,62 @@ td#crumb a {
119td#crumb a:hover { 119td#crumb a:hover {
120 color: #eee; 120 color: #eee;
121} 121}
122 122
123td#search { 123td#search {
124 text-align: right; 124 text-align: right;
125 vertical-align: center; 125 vertical-align: center;
126 padding-right: 0.5em; 126 padding-right: 0.5em;
127} 127}
128 128
129td#search form { 129td#search form {
130 margin: 0px; 130 margin: 0px;
131 padding: 0px; 131 padding: 0px;
132} 132}
133 133
134td#search input { 134td#search input {
135 font-size: 9pt; 135 font-size: 9pt;
136 padding: 0px; 136 padding: 0px;
137 width: 10em; 137 width: 10em;
138 border: solid 1px #333; 138 border: solid 1px #333;
139 color: #333; 139 color: #333;
140 background-color: #fff; 140 background-color: #fff;
141} 141}
142 142
143td#summary { 143div#summary {
144 vertical-align: top; 144 vertical-align: top;
145 padding-bottom: 1em; 145 margin-bottom: 1em;
146} 146}
147 147
148td#archivelist { 148table#downloads {
149 padding-bottom: 1em;
150}
151
152td#archivelist table {
153 float: right; 149 float: right;
154 border-collapse: collapse; 150 border-collapse: collapse;
155 border: solid 1px #777; 151 border: solid 1px #777;
152 margin-left: 0.5em;
153 margin-bottom: 0.5em;
156} 154}
157 155
158td#archivelist table th { 156table#downloads th {
159 background-color: #ccc; 157 background-color: #ccc;
160} 158}
161 159
162td#content { 160td#content {
163 padding: 1em 0.5em; 161 padding: 1em 0.5em;
164} 162}
165 163
166div#blob { 164div#blob {
167 border: solid 1px black; 165 border: solid 1px black;
168} 166}
169 167
170div.error { 168div.error {
171 color: red; 169 color: red;
172 font-weight: bold; 170 font-weight: bold;
173 margin: 1em 2em; 171 margin: 1em 2em;
174} 172}
175 173
176td.ls-blob, td.ls-dir, td.ls-mod { 174td.ls-blob, td.ls-dir, td.ls-mod {
177 font-family: monospace; 175 font-family: monospace;
178} 176}
179 177
180div.ls-dir a { 178div.ls-dir a {
181 font-weight: bold; 179 font-weight: bold;
182} 180}
diff --git a/cgit.h b/cgit.h
index 3938633..5c55bec 100644
--- a/cgit.h
+++ b/cgit.h
@@ -47,48 +47,49 @@
47#define TM_YEAR (TM_DAY * 365) 47#define TM_YEAR (TM_DAY * 365)
48#define TM_MONTH (TM_YEAR / 12.0) 48#define TM_MONTH (TM_YEAR / 12.0)
49 49
50 50
51typedef void (*configfn)(const char *name, const char *value); 51typedef void (*configfn)(const char *name, const char *value);
52typedef void (*filepair_fn)(struct diff_filepair *pair); 52typedef void (*filepair_fn)(struct diff_filepair *pair);
53typedef void (*linediff_fn)(char *line, int len); 53typedef void (*linediff_fn)(char *line, int len);
54 54
55struct cacheitem { 55struct cacheitem {
56 char *name; 56 char *name;
57 struct stat st; 57 struct stat st;
58 int ttl; 58 int ttl;
59 int fd; 59 int fd;
60}; 60};
61 61
62struct repoinfo { 62struct repoinfo {
63 char *url; 63 char *url;
64 char *name; 64 char *name;
65 char *path; 65 char *path;
66 char *desc; 66 char *desc;
67 char *owner; 67 char *owner;
68 char *defbranch; 68 char *defbranch;
69 char *group; 69 char *group;
70 char *module_link; 70 char *module_link;
71 char *readme;
71 int snapshots; 72 int snapshots;
72 int enable_log_filecount; 73 int enable_log_filecount;
73 int enable_log_linecount; 74 int enable_log_linecount;
74}; 75};
75 76
76struct repolist { 77struct repolist {
77 int length; 78 int length;
78 int count; 79 int count;
79 struct repoinfo *repos; 80 struct repoinfo *repos;
80}; 81};
81 82
82struct commitinfo { 83struct commitinfo {
83 struct commit *commit; 84 struct commit *commit;
84 char *author; 85 char *author;
85 char *author_email; 86 char *author_email;
86 unsigned long author_date; 87 unsigned long author_date;
87 char *committer; 88 char *committer;
88 char *committer_email; 89 char *committer_email;
89 unsigned long committer_date; 90 unsigned long committer_date;
90 char *subject; 91 char *subject;
91 char *msg; 92 char *msg;
92}; 93};
93 94
94struct taginfo { 95struct taginfo {
diff --git a/cgitrc b/cgitrc
index eaa9ce3..054a708 100644
--- a/cgitrc
+++ b/cgitrc
@@ -87,24 +87,25 @@
87#cache-root-ttl=5 87#cache-root-ttl=5
88 88
89## ttl for repo summary page 89## ttl for repo summary page
90#cache-repo-ttl=5 90#cache-repo-ttl=5
91 91
92## ttl for other dynamic pages 92## ttl for other dynamic pages
93#cache-dynamic-ttl=5 93#cache-dynamic-ttl=5
94 94
95## ttl for static pages (addressed by SHA-1) 95## ttl for static pages (addressed by SHA-1)
96#cache-static-ttl=-1 96#cache-static-ttl=-1
97 97
98 98
99 99
100## Example repository entry. Required values are repo.url and repo.path (each 100## Example repository entry. Required values are repo.url and repo.path (each
101## repository section must start with repo.url). 101## repository section must start with repo.url).
102#repo.url=cgit 102#repo.url=cgit
103#repo.name=cgit 103#repo.name=cgit
104#repo.desc=the caching cgi for git 104#repo.desc=the caching cgi for git
105#repo.path=/pub/git/cgit 105#repo.path=/pub/git/cgit
106#repo.owner=Lars Hjemli 106#repo.owner=Lars Hjemli
107 #repo.snapshots=1 # override a sitewide snapshot-setting 107 #repo.snapshots=1 # override a sitewide snapshot-setting
108 #repo.enable-log-filecount=0 # override the default filecount setting 108 #repo.enable-log-filecount=0 # override the default filecount setting
109 #repo.enable-log-linecount=0 # override the default linecount setting 109 #repo.enable-log-linecount=0 # override the default linecount setting
110 #repo.module-link=/git/%s/commit/?id=%s # override the standard module-link 110 #repo.module-link=/git/%s/commit/?id=%s # override the standard module-link
111 #repo.readme=info/web/readme # specify a file to include on summary page
diff --git a/shared.c b/shared.c
index ce3ca4f..e3123a8 100644
--- a/shared.c
+++ b/shared.c
@@ -86,48 +86,49 @@ struct repoinfo *add_repo(const char *url)
86 struct repoinfo *ret; 86 struct repoinfo *ret;
87 87
88 if (++cgit_repolist.count > cgit_repolist.length) { 88 if (++cgit_repolist.count > cgit_repolist.length) {
89 if (cgit_repolist.length == 0) 89 if (cgit_repolist.length == 0)
90 cgit_repolist.length = 8; 90 cgit_repolist.length = 8;
91 else 91 else
92 cgit_repolist.length *= 2; 92 cgit_repolist.length *= 2;
93 cgit_repolist.repos = xrealloc(cgit_repolist.repos, 93 cgit_repolist.repos = xrealloc(cgit_repolist.repos,
94 cgit_repolist.length * 94 cgit_repolist.length *
95 sizeof(struct repoinfo)); 95 sizeof(struct repoinfo));
96 } 96 }
97 97
98 ret = &cgit_repolist.repos[cgit_repolist.count-1]; 98 ret = &cgit_repolist.repos[cgit_repolist.count-1];
99 ret->url = xstrdup(url); 99 ret->url = xstrdup(url);
100 ret->name = ret->url; 100 ret->name = ret->url;
101 ret->path = NULL; 101 ret->path = NULL;
102 ret->desc = NULL; 102 ret->desc = NULL;
103 ret->owner = NULL; 103 ret->owner = NULL;
104 ret->group = cgit_repo_group; 104 ret->group = cgit_repo_group;
105 ret->defbranch = "master"; 105 ret->defbranch = "master";
106 ret->snapshots = cgit_snapshots; 106 ret->snapshots = cgit_snapshots;
107 ret->enable_log_filecount = cgit_enable_log_filecount; 107 ret->enable_log_filecount = cgit_enable_log_filecount;
108 ret->enable_log_linecount = cgit_enable_log_linecount; 108 ret->enable_log_linecount = cgit_enable_log_linecount;
109 ret->module_link = cgit_module_link; 109 ret->module_link = cgit_module_link;
110 ret->readme = NULL;
110 return ret; 111 return ret;
111} 112}
112 113
113struct repoinfo *cgit_get_repoinfo(const char *url) 114struct repoinfo *cgit_get_repoinfo(const char *url)
114{ 115{
115 int i; 116 int i;
116 struct repoinfo *repo; 117 struct repoinfo *repo;
117 118
118 for (i=0; i<cgit_repolist.count; i++) { 119 for (i=0; i<cgit_repolist.count; i++) {
119 repo = &cgit_repolist.repos[i]; 120 repo = &cgit_repolist.repos[i];
120 if (!strcmp(repo->url, url)) 121 if (!strcmp(repo->url, url))
121 return repo; 122 return repo;
122 } 123 }
123 return NULL; 124 return NULL;
124} 125}
125 126
126void cgit_global_config_cb(const char *name, const char *value) 127void cgit_global_config_cb(const char *name, const char *value)
127{ 128{
128 if (!strcmp(name, "root-title")) 129 if (!strcmp(name, "root-title"))
129 cgit_root_title = xstrdup(value); 130 cgit_root_title = xstrdup(value);
130 else if (!strcmp(name, "css")) 131 else if (!strcmp(name, "css"))
131 cgit_css = xstrdup(value); 132 cgit_css = xstrdup(value);
132 else if (!strcmp(name, "logo")) 133 else if (!strcmp(name, "logo"))
133 cgit_logo = xstrdup(value); 134 cgit_logo = xstrdup(value);
@@ -166,49 +167,54 @@ void cgit_global_config_cb(const char *name, const char *value)
166 else if (!strcmp(name, "agefile")) 167 else if (!strcmp(name, "agefile"))
167 cgit_agefile = xstrdup(value); 168 cgit_agefile = xstrdup(value);
168 else if (!strcmp(name, "repo.group")) 169 else if (!strcmp(name, "repo.group"))
169 cgit_repo_group = xstrdup(value); 170 cgit_repo_group = xstrdup(value);
170 else if (!strcmp(name, "repo.url")) 171 else if (!strcmp(name, "repo.url"))
171 cgit_repo = add_repo(value); 172 cgit_repo = add_repo(value);
172 else if (!strcmp(name, "repo.name")) 173 else if (!strcmp(name, "repo.name"))
173 cgit_repo->name = xstrdup(value); 174 cgit_repo->name = xstrdup(value);
174 else if (cgit_repo && !strcmp(name, "repo.path")) 175 else if (cgit_repo && !strcmp(name, "repo.path"))
175 cgit_repo->path = xstrdup(value); 176 cgit_repo->path = xstrdup(value);
176 else if (cgit_repo && !strcmp(name, "repo.desc")) 177 else if (cgit_repo && !strcmp(name, "repo.desc"))
177 cgit_repo->desc = xstrdup(value); 178 cgit_repo->desc = xstrdup(value);
178 else if (cgit_repo && !strcmp(name, "repo.owner")) 179 else if (cgit_repo && !strcmp(name, "repo.owner"))
179 cgit_repo->owner = xstrdup(value); 180 cgit_repo->owner = xstrdup(value);
180 else if (cgit_repo && !strcmp(name, "repo.defbranch")) 181 else if (cgit_repo && !strcmp(name, "repo.defbranch"))
181 cgit_repo->defbranch = xstrdup(value); 182 cgit_repo->defbranch = xstrdup(value);
182 else if (cgit_repo && !strcmp(name, "repo.snapshots")) 183 else if (cgit_repo && !strcmp(name, "repo.snapshots"))
183 cgit_repo->snapshots = cgit_snapshots * atoi(value); 184 cgit_repo->snapshots = cgit_snapshots * atoi(value);
184 else if (cgit_repo && !strcmp(name, "repo.enable-log-filecount")) 185 else if (cgit_repo && !strcmp(name, "repo.enable-log-filecount"))
185 cgit_repo->enable_log_filecount = cgit_enable_log_filecount * atoi(value); 186 cgit_repo->enable_log_filecount = cgit_enable_log_filecount * atoi(value);
186 else if (cgit_repo && !strcmp(name, "repo.enable-log-linecount")) 187 else if (cgit_repo && !strcmp(name, "repo.enable-log-linecount"))
187 cgit_repo->enable_log_linecount = cgit_enable_log_linecount * atoi(value); 188 cgit_repo->enable_log_linecount = cgit_enable_log_linecount * atoi(value);
188 else if (cgit_repo && !strcmp(name, "repo.module-link")) 189 else if (cgit_repo && !strcmp(name, "repo.module-link"))
189 cgit_repo->module_link= xstrdup(value); 190 cgit_repo->module_link= xstrdup(value);
190 else if (!strcmp(name, "include")) 191 else if (cgit_repo && !strcmp(name, "repo.readme") && value != NULL) {
192 if (*value == '/')
193 cgit_repo->readme = xstrdup(value);
194 else
195 cgit_repo->readme = xstrdup(fmt("%s/%s", cgit_repo->path, value));
196 } else if (!strcmp(name, "include"))
191 cgit_read_config(value, cgit_global_config_cb); 197 cgit_read_config(value, cgit_global_config_cb);
192} 198}
193 199
194void cgit_querystring_cb(const char *name, const char *value) 200void cgit_querystring_cb(const char *name, const char *value)
195{ 201{
196 if (!strcmp(name,"r")) { 202 if (!strcmp(name,"r")) {
197 cgit_query_repo = xstrdup(value); 203 cgit_query_repo = xstrdup(value);
198 cgit_repo = cgit_get_repoinfo(value); 204 cgit_repo = cgit_get_repoinfo(value);
199 } else if (!strcmp(name, "p")) { 205 } else if (!strcmp(name, "p")) {
200 cgit_query_page = xstrdup(value); 206 cgit_query_page = xstrdup(value);
201 cgit_cmd = cgit_get_cmd_index(value); 207 cgit_cmd = cgit_get_cmd_index(value);
202 } else if (!strcmp(name, "url")) { 208 } else if (!strcmp(name, "url")) {
203 cgit_parse_url(value); 209 cgit_parse_url(value);
204 } else if (!strcmp(name, "q")) { 210 } else if (!strcmp(name, "q")) {
205 cgit_query_search = xstrdup(value); 211 cgit_query_search = xstrdup(value);
206 } else if (!strcmp(name, "h")) { 212 } else if (!strcmp(name, "h")) {
207 cgit_query_head = xstrdup(value); 213 cgit_query_head = xstrdup(value);
208 cgit_query_has_symref = 1; 214 cgit_query_has_symref = 1;
209 } else if (!strcmp(name, "id")) { 215 } else if (!strcmp(name, "id")) {
210 cgit_query_sha1 = xstrdup(value); 216 cgit_query_sha1 = xstrdup(value);
211 cgit_query_has_sha1 = 1; 217 cgit_query_has_sha1 = 1;
212 } else if (!strcmp(name, "id2")) { 218 } else if (!strcmp(name, "id2")) {
213 cgit_query_sha2 = xstrdup(value); 219 cgit_query_sha2 = xstrdup(value);
214 cgit_query_has_sha1 = 1; 220 cgit_query_has_sha1 = 1;
diff --git a/ui-summary.c b/ui-summary.c
index 5799773..5c1fc33 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -132,79 +132,81 @@ static int cgit_print_archive_cb(const char *refname, const unsigned char *sha1,
132{ 132{
133 struct tag *tag; 133 struct tag *tag;
134 struct taginfo *info; 134 struct taginfo *info;
135 struct object *obj; 135 struct object *obj;
136 char buf[256], *url; 136 char buf[256], *url;
137 unsigned char fileid[20]; 137 unsigned char fileid[20];
138 138
139 if (prefixcmp(refname, "refs/archives")) 139 if (prefixcmp(refname, "refs/archives"))
140 return 0; 140 return 0;
141 strncpy(buf, refname+14, sizeof(buf)); 141 strncpy(buf, refname+14, sizeof(buf));
142 obj = parse_object(sha1); 142 obj = parse_object(sha1);
143 if (!obj) 143 if (!obj)
144 return 1; 144 return 1;
145 if (obj->type == OBJ_TAG) { 145 if (obj->type == OBJ_TAG) {
146 tag = lookup_tag(sha1); 146 tag = lookup_tag(sha1);
147 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) 147 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag)))
148 return 0; 148 return 0;
149 hashcpy(fileid, tag->tagged->sha1); 149 hashcpy(fileid, tag->tagged->sha1);
150 } else if (obj->type != OBJ_BLOB) { 150 } else if (obj->type != OBJ_BLOB) {
151 return 0; 151 return 0;
152 } else { 152 } else {
153 hashcpy(fileid, sha1); 153 hashcpy(fileid, sha1);
154 } 154 }
155 if (!header) { 155 if (!header) {
156 html("<table>"); 156 html("<table id='downloads'>");
157 html("<tr><th>Downloads</th></tr>"); 157 html("<tr><th>Downloads</th></tr>");
158 header = 1; 158 header = 1;
159 } 159 }
160 html("<tr><td>"); 160 html("<tr><td>");
161 url = cgit_pageurl(cgit_query_repo, "blob", 161 url = cgit_pageurl(cgit_query_repo, "blob",
162 fmt("id=%s&path=%s", sha1_to_hex(fileid), 162 fmt("id=%s&path=%s", sha1_to_hex(fileid),
163 buf)); 163 buf));
164 html_link_open(url, NULL, NULL); 164 html_link_open(url, NULL, NULL);
165 html_txt(buf); 165 html_txt(buf);
166 html_link_close(); 166 html_link_close();
167 html("</td><tr>"); 167 html("</td><tr>");
168 return 0; 168 return 0;
169} 169}
170 170
171static void cgit_print_branches() 171static void cgit_print_branches()
172{ 172{
173 html("<tr class='nohover'><th class='left'>Branch</th>" 173 html("<tr class='nohover'><th class='left'>Branch</th>"
174 "<th class='left'>Idle</th>" 174 "<th class='left'>Idle</th>"
175 "<th class='left'>Author</th>" 175 "<th class='left'>Author</th>"
176 "<th class='left'>Head commit</th></tr>\n"); 176 "<th class='left'>Head commit</th></tr>\n");
177 for_each_branch_ref(cgit_print_branch_cb, NULL); 177 for_each_branch_ref(cgit_print_branch_cb, NULL);
178} 178}
179 179
180static void cgit_print_tags() 180static void cgit_print_tags()
181{ 181{
182 header = 0; 182 header = 0;
183 for_each_tag_ref(cgit_print_tag_cb, NULL); 183 for_each_tag_ref(cgit_print_tag_cb, NULL);
184} 184}
185 185
186static void cgit_print_archives() 186static void cgit_print_archives()
187{ 187{
188 header = 0; 188 header = 0;
189 for_each_ref(cgit_print_archive_cb, NULL); 189 for_each_ref(cgit_print_archive_cb, NULL);
190 if (header) 190 if (header)
191 html("</table>"); 191 html("</table>");
192} 192}
193 193
194void cgit_print_summary() 194void cgit_print_summary()
195{ 195{
196 html("<table class='list nowrap'>"); 196 html("<div id='summary'>");
197 html("<tr class='nohover'><td id='summary' colspan='3'>"); 197 cgit_print_archives();
198 html("<h2>"); 198 html("<h2>");
199 html_txt(cgit_repo->name); 199 html_txt(cgit_repo->name);
200 html(" - "); 200 html(" - ");
201 html_txt(cgit_repo->desc); 201 html_txt(cgit_repo->desc);
202 html("</h2>"); 202 html("</h2>");
203 html("</td><td id='archivelist'>"); 203 if (cgit_repo->readme)
204 cgit_print_archives(); 204 html_include(cgit_repo->readme);
205 html("</td></tr>"); 205 html("</div>");
206
207 html("<table class='list nowrap'>");
206 cgit_print_branches(); 208 cgit_print_branches();
207 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>"); 209 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
208 cgit_print_tags(); 210 cgit_print_tags();
209 html("</table>"); 211 html("</table>");
210} 212}