summaryrefslogtreecommitdiffabout
path: root/ui-shared.c
Unidiff
Diffstat (limited to 'ui-shared.c') (more/less context) (ignore whitespace changes)
-rw-r--r--ui-shared.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/ui-shared.c b/ui-shared.c
index 4818e70..c23bc75 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -1,304 +1,309 @@
1/* ui-shared.c: common web output functions 1/* ui-shared.c: common web output functions
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include "cgit.h" 9#include "cgit.h"
10#include "cmd.h" 10#include "cmd.h"
11#include "html.h" 11#include "html.h"
12 12
13const char cgit_doctype[] = 13const char cgit_doctype[] =
14"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" 14"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
15" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; 15" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
16 16
17static char *http_date(time_t t) 17static char *http_date(time_t t)
18{ 18{
19 static char day[][4] = 19 static char day[][4] =
20 {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 20 {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
21 static char month[][4] = 21 static char month[][4] =
22 {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 22 {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
23 "Jul", "Aug", "Sep", "Oct", "Now", "Dec"}; 23 "Jul", "Aug", "Sep", "Oct", "Now", "Dec"};
24 struct tm *tm = gmtime(&t); 24 struct tm *tm = gmtime(&t);
25 return fmt("%s, %02d %s %04d %02d:%02d:%02d GMT", day[tm->tm_wday], 25 return fmt("%s, %02d %s %04d %02d:%02d:%02d GMT", day[tm->tm_wday],
26 tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year, 26 tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year,
27 tm->tm_hour, tm->tm_min, tm->tm_sec); 27 tm->tm_hour, tm->tm_min, tm->tm_sec);
28} 28}
29 29
30void cgit_print_error(char *msg) 30void cgit_print_error(char *msg)
31{ 31{
32 html("<div class='error'>"); 32 html("<div class='error'>");
33 html_txt(msg); 33 html_txt(msg);
34 html("</div>\n"); 34 html("</div>\n");
35} 35}
36 36
37char *cgit_hosturl() 37char *cgit_hosturl()
38{ 38{
39 char *host, *port; 39 char *host, *port;
40 40
41 host = getenv("SERVER_NAME"); 41 host = getenv("HTTP_HOST");
42 if (!host) 42 if (host) {
43 return NULL;
44 port = getenv("SERVER_PORT");
45 if (port && atoi(port) != 80)
46 host = xstrdup(fmt("%s:%d", host, atoi(port)));
47 else
48 host = xstrdup(host); 43 host = xstrdup(host);
44 } else {
45 host = getenv("SERVER_NAME");
46 if (!host)
47 return NULL;
48 port = getenv("SERVER_PORT");
49 if (port && atoi(port) != 80)
50 host = xstrdup(fmt("%s:%d", host, atoi(port)));
51 else
52 host = xstrdup(host);
53 }
49 return host; 54 return host;
50} 55}
51 56
52char *cgit_rooturl() 57char *cgit_rooturl()
53{ 58{
54 if (ctx.cfg.virtual_root) 59 if (ctx.cfg.virtual_root)
55 return fmt("%s/", ctx.cfg.virtual_root); 60 return fmt("%s/", ctx.cfg.virtual_root);
56 else 61 else
57 return ctx.cfg.script_name; 62 return ctx.cfg.script_name;
58} 63}
59 64
60char *cgit_repourl(const char *reponame) 65char *cgit_repourl(const char *reponame)
61{ 66{
62 if (ctx.cfg.virtual_root) { 67 if (ctx.cfg.virtual_root) {
63 return fmt("%s/%s/", ctx.cfg.virtual_root, reponame); 68 return fmt("%s/%s/", ctx.cfg.virtual_root, reponame);
64 } else { 69 } else {
65 return fmt("?r=%s", reponame); 70 return fmt("?r=%s", reponame);
66 } 71 }
67} 72}
68 73
69char *cgit_fileurl(const char *reponame, const char *pagename, 74char *cgit_fileurl(const char *reponame, const char *pagename,
70 const char *filename, const char *query) 75 const char *filename, const char *query)
71{ 76{
72 char *tmp; 77 char *tmp;
73 char *delim; 78 char *delim;
74 79
75 if (ctx.cfg.virtual_root) { 80 if (ctx.cfg.virtual_root) {
76 tmp = fmt("%s/%s/%s/%s", ctx.cfg.virtual_root, reponame, 81 tmp = fmt("%s/%s/%s/%s", ctx.cfg.virtual_root, reponame,
77 pagename, (filename ? filename:"")); 82 pagename, (filename ? filename:""));
78 delim = "?"; 83 delim = "?";
79 } else { 84 } else {
80 tmp = fmt("?url=%s/%s/%s", reponame, pagename, 85 tmp = fmt("?url=%s/%s/%s", reponame, pagename,
81 (filename ? filename : "")); 86 (filename ? filename : ""));
82 delim = "&"; 87 delim = "&";
83 } 88 }
84 if (query) 89 if (query)
85 tmp = fmt("%s%s%s", tmp, delim, query); 90 tmp = fmt("%s%s%s", tmp, delim, query);
86 return tmp; 91 return tmp;
87} 92}
88 93
89char *cgit_pageurl(const char *reponame, const char *pagename, 94char *cgit_pageurl(const char *reponame, const char *pagename,
90 const char *query) 95 const char *query)
91{ 96{
92 return cgit_fileurl(reponame,pagename,0,query); 97 return cgit_fileurl(reponame,pagename,0,query);
93} 98}
94 99
95const char *cgit_repobasename(const char *reponame) 100const char *cgit_repobasename(const char *reponame)
96{ 101{
97 /* I assume we don't need to store more than one repo basename */ 102 /* I assume we don't need to store more than one repo basename */
98 static char rvbuf[1024]; 103 static char rvbuf[1024];
99 int p; 104 int p;
100 const char *rv; 105 const char *rv;
101 strncpy(rvbuf,reponame,sizeof(rvbuf)); 106 strncpy(rvbuf,reponame,sizeof(rvbuf));
102 if(rvbuf[sizeof(rvbuf)-1]) 107 if(rvbuf[sizeof(rvbuf)-1])
103 die("cgit_repobasename: truncated repository name '%s'", reponame); 108 die("cgit_repobasename: truncated repository name '%s'", reponame);
104 p = strlen(rvbuf)-1; 109 p = strlen(rvbuf)-1;
105 /* strip trailing slashes */ 110 /* strip trailing slashes */
106 while(p && rvbuf[p]=='/') rvbuf[p--]=0; 111 while(p && rvbuf[p]=='/') rvbuf[p--]=0;
107 /* strip trailing .git */ 112 /* strip trailing .git */
108 if(p>=3 && !strncmp(&rvbuf[p-3],".git",4)) { 113 if(p>=3 && !strncmp(&rvbuf[p-3],".git",4)) {
109 p -= 3; rvbuf[p--] = 0; 114 p -= 3; rvbuf[p--] = 0;
110 } 115 }
111 /* strip more trailing slashes if any */ 116 /* strip more trailing slashes if any */
112 while( p && rvbuf[p]=='/') rvbuf[p--]=0; 117 while( p && rvbuf[p]=='/') rvbuf[p--]=0;
113 /* find last slash in the remaining string */ 118 /* find last slash in the remaining string */
114 rv = strrchr(rvbuf,'/'); 119 rv = strrchr(rvbuf,'/');
115 if(rv) 120 if(rv)
116 return ++rv; 121 return ++rv;
117 return rvbuf; 122 return rvbuf;
118} 123}
119 124
120char *cgit_currurl() 125char *cgit_currurl()
121{ 126{
122 if (!ctx.cfg.virtual_root) 127 if (!ctx.cfg.virtual_root)
123 return ctx.cfg.script_name; 128 return ctx.cfg.script_name;
124 else if (ctx.qry.page) 129 else if (ctx.qry.page)
125 return fmt("%s/%s/%s/", ctx.cfg.virtual_root, ctx.qry.repo, ctx.qry.page); 130 return fmt("%s/%s/%s/", ctx.cfg.virtual_root, ctx.qry.repo, ctx.qry.page);
126 else if (ctx.qry.repo) 131 else if (ctx.qry.repo)
127 return fmt("%s/%s/", ctx.cfg.virtual_root, ctx.qry.repo); 132 return fmt("%s/%s/", ctx.cfg.virtual_root, ctx.qry.repo);
128 else 133 else
129 return fmt("%s/", ctx.cfg.virtual_root); 134 return fmt("%s/", ctx.cfg.virtual_root);
130} 135}
131 136
132static void site_url(char *page, char *search, int ofs) 137static void site_url(char *page, char *search, int ofs)
133{ 138{
134 char *delim = "?"; 139 char *delim = "?";
135 140
136 if (ctx.cfg.virtual_root) { 141 if (ctx.cfg.virtual_root) {
137 html_attr(ctx.cfg.virtual_root); 142 html_attr(ctx.cfg.virtual_root);
138 if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/') 143 if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/')
139 html("/"); 144 html("/");
140 } else 145 } else
141 html(ctx.cfg.script_name); 146 html(ctx.cfg.script_name);
142 147
143 if (page) { 148 if (page) {
144 htmlf("?p=%s", page); 149 htmlf("?p=%s", page);
145 delim = "&"; 150 delim = "&";
146 } 151 }
147 if (search) { 152 if (search) {
148 html(delim); 153 html(delim);
149 html("q="); 154 html("q=");
150 html_attr(search); 155 html_attr(search);
151 delim = "&"; 156 delim = "&";
152 } 157 }
153 if (ofs) { 158 if (ofs) {
154 html(delim); 159 html(delim);
155 htmlf("ofs=%d", ofs); 160 htmlf("ofs=%d", ofs);
156 } 161 }
157} 162}
158 163
159static void site_link(char *page, char *name, char *title, char *class, 164static void site_link(char *page, char *name, char *title, char *class,
160 char *search, int ofs) 165 char *search, int ofs)
161{ 166{
162 html("<a"); 167 html("<a");
163 if (title) { 168 if (title) {
164 html(" title='"); 169 html(" title='");
165 html_attr(title); 170 html_attr(title);
166 html("'"); 171 html("'");
167 } 172 }
168 if (class) { 173 if (class) {
169 html(" class='"); 174 html(" class='");
170 html_attr(class); 175 html_attr(class);
171 html("'"); 176 html("'");
172 } 177 }
173 html(" href='"); 178 html(" href='");
174 site_url(page, search, ofs); 179 site_url(page, search, ofs);
175 html("'>"); 180 html("'>");
176 html_txt(name); 181 html_txt(name);
177 html("</a>"); 182 html("</a>");
178} 183}
179 184
180void cgit_index_link(char *name, char *title, char *class, char *pattern, 185void cgit_index_link(char *name, char *title, char *class, char *pattern,
181 int ofs) 186 int ofs)
182{ 187{
183 site_link(NULL, name, title, class, pattern, ofs); 188 site_link(NULL, name, title, class, pattern, ofs);
184} 189}
185 190
186static char *repolink(char *title, char *class, char *page, char *head, 191static char *repolink(char *title, char *class, char *page, char *head,
187 char *path) 192 char *path)
188{ 193{
189 char *delim = "?"; 194 char *delim = "?";
190 195
191 html("<a"); 196 html("<a");
192 if (title) { 197 if (title) {
193 html(" title='"); 198 html(" title='");
194 html_attr(title); 199 html_attr(title);
195 html("'"); 200 html("'");
196 } 201 }
197 if (class) { 202 if (class) {
198 html(" class='"); 203 html(" class='");
199 html_attr(class); 204 html_attr(class);
200 html("'"); 205 html("'");
201 } 206 }
202 html(" href='"); 207 html(" href='");
203 if (ctx.cfg.virtual_root) { 208 if (ctx.cfg.virtual_root) {
204 html_attr(ctx.cfg.virtual_root); 209 html_attr(ctx.cfg.virtual_root);
205 if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/') 210 if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/')
206 html("/"); 211 html("/");
207 html_attr(ctx.repo->url); 212 html_attr(ctx.repo->url);
208 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/') 213 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
209 html("/"); 214 html("/");
210 if (page) { 215 if (page) {
211 html(page); 216 html(page);
212 html("/"); 217 html("/");
213 if (path) 218 if (path)
214 html_attr(path); 219 html_attr(path);
215 } 220 }
216 } else { 221 } else {
217 html(ctx.cfg.script_name); 222 html(ctx.cfg.script_name);
218 html("?url="); 223 html("?url=");
219 html_attr(ctx.repo->url); 224 html_attr(ctx.repo->url);
220 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/') 225 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
221 html("/"); 226 html("/");
222 if (page) { 227 if (page) {
223 html(page); 228 html(page);
224 html("/"); 229 html("/");
225 if (path) 230 if (path)
226 html_attr(path); 231 html_attr(path);
227 } 232 }
228 delim = "&amp;"; 233 delim = "&amp;";
229 } 234 }
230 if (head && strcmp(head, ctx.repo->defbranch)) { 235 if (head && strcmp(head, ctx.repo->defbranch)) {
231 html(delim); 236 html(delim);
232 html("h="); 237 html("h=");
233 html_attr(head); 238 html_attr(head);
234 delim = "&amp;"; 239 delim = "&amp;";
235 } 240 }
236 return fmt("%s", delim); 241 return fmt("%s", delim);
237} 242}
238 243
239static void reporevlink(char *page, char *name, char *title, char *class, 244static void reporevlink(char *page, char *name, char *title, char *class,
240 char *head, char *rev, char *path) 245 char *head, char *rev, char *path)
241{ 246{
242 char *delim; 247 char *delim;
243 248
244 delim = repolink(title, class, page, head, path); 249 delim = repolink(title, class, page, head, path);
245 if (rev && strcmp(rev, ctx.qry.head)) { 250 if (rev && strcmp(rev, ctx.qry.head)) {
246 html(delim); 251 html(delim);
247 html("id="); 252 html("id=");
248 html_attr(rev); 253 html_attr(rev);
249 } 254 }
250 html("'>"); 255 html("'>");
251 html_txt(name); 256 html_txt(name);
252 html("</a>"); 257 html("</a>");
253} 258}
254 259
255void cgit_tree_link(char *name, char *title, char *class, char *head, 260void cgit_tree_link(char *name, char *title, char *class, char *head,
256 char *rev, char *path) 261 char *rev, char *path)
257{ 262{
258 reporevlink("tree", name, title, class, head, rev, path); 263 reporevlink("tree", name, title, class, head, rev, path);
259} 264}
260 265
261void cgit_plain_link(char *name, char *title, char *class, char *head, 266void cgit_plain_link(char *name, char *title, char *class, char *head,
262 char *rev, char *path) 267 char *rev, char *path)
263{ 268{
264 reporevlink("plain", name, title, class, head, rev, path); 269 reporevlink("plain", name, title, class, head, rev, path);
265} 270}
266 271
267void cgit_log_link(char *name, char *title, char *class, char *head, 272void cgit_log_link(char *name, char *title, char *class, char *head,
268 char *rev, char *path, int ofs, char *grep, char *pattern) 273 char *rev, char *path, int ofs, char *grep, char *pattern)
269{ 274{
270 char *delim; 275 char *delim;
271 276
272 delim = repolink(title, class, "log", head, path); 277 delim = repolink(title, class, "log", head, path);
273 if (rev && strcmp(rev, ctx.qry.head)) { 278 if (rev && strcmp(rev, ctx.qry.head)) {
274 html(delim); 279 html(delim);
275 html("id="); 280 html("id=");
276 html_attr(rev); 281 html_attr(rev);
277 delim = "&"; 282 delim = "&";
278 } 283 }
279 if (grep && pattern) { 284 if (grep && pattern) {
280 html(delim); 285 html(delim);
281 html("qt="); 286 html("qt=");
282 html_attr(grep); 287 html_attr(grep);
283 delim = "&"; 288 delim = "&";
284 html(delim); 289 html(delim);
285 html("q="); 290 html("q=");
286 html_attr(pattern); 291 html_attr(pattern);
287 } 292 }
288 if (ofs > 0) { 293 if (ofs > 0) {
289 html(delim); 294 html(delim);
290 html("ofs="); 295 html("ofs=");
291 htmlf("%d", ofs); 296 htmlf("%d", ofs);
292 } 297 }
293 html("'>"); 298 html("'>");
294 html_txt(name); 299 html_txt(name);
295 html("</a>"); 300 html("</a>");
296} 301}
297 302
298void cgit_commit_link(char *name, char *title, char *class, char *head, 303void cgit_commit_link(char *name, char *title, char *class, char *head,
299 char *rev) 304 char *rev)
300{ 305{
301 if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) { 306 if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) {
302 name[ctx.cfg.max_msg_len] = '\0'; 307 name[ctx.cfg.max_msg_len] = '\0';
303 name[ctx.cfg.max_msg_len - 1] = '.'; 308 name[ctx.cfg.max_msg_len - 1] = '.';
304 name[ctx.cfg.max_msg_len - 2] = '.'; 309 name[ctx.cfg.max_msg_len - 2] = '.';