summaryrefslogtreecommitdiffabout
path: root/cgit.c
Unidiff
Diffstat (limited to 'cgit.c') (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/cgit.c b/cgit.c
index 09c857c..808ffe9 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,192 +1,200 @@
1/* cgit.c: cgi for the git scm
2 *
3 * Copyright (C) 2006 Lars Hjemli
4 *
5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text)
7 */
8
1#include "cgit.h" 9#include "cgit.h"
2 10
3static const char cgit_doctype[] = 11static const char cgit_doctype[] =
4"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" 12"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
5" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; 13" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
6 14
7static const char cgit_error[] = 15static const char cgit_error[] =
8"<div class='error'>%s</div>"; 16"<div class='error'>%s</div>";
9 17
10static const char cgit_lib_error[] = 18static const char cgit_lib_error[] =
11"<div class='error'>%s: %s</div>"; 19"<div class='error'>%s: %s</div>";
12 20
13int htmlfd = 0; 21int htmlfd = 0;
14 22
15char *cgit_root = "/usr/src/git"; 23char *cgit_root = "/usr/src/git";
16char *cgit_root_title = "Git repository browser"; 24char *cgit_root_title = "Git repository browser";
17char *cgit_css = "/cgit.css"; 25char *cgit_css = "/cgit.css";
18char *cgit_logo = "/git-logo.png"; 26char *cgit_logo = "/git-logo.png";
19char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/"; 27char *cgit_logo_link = "http://www.kernel.org/pub/software/scm/git/docs/";
20char *cgit_virtual_root = NULL; 28char *cgit_virtual_root = NULL;
21 29
22char *cgit_cache_root = "/var/cache/cgit"; 30char *cgit_cache_root = "/var/cache/cgit";
23 31
24int cgit_cache_root_ttl = 5; 32int cgit_cache_root_ttl = 5;
25int cgit_cache_repo_ttl = 5; 33int cgit_cache_repo_ttl = 5;
26int cgit_cache_dynamic_ttl = 5; 34int cgit_cache_dynamic_ttl = 5;
27int cgit_cache_static_ttl = -1; 35int cgit_cache_static_ttl = -1;
28int cgit_cache_max_create_time = 5; 36int cgit_cache_max_create_time = 5;
29 37
30char *cgit_repo_name = NULL; 38char *cgit_repo_name = NULL;
31char *cgit_repo_desc = NULL; 39char *cgit_repo_desc = NULL;
32char *cgit_repo_owner = NULL; 40char *cgit_repo_owner = NULL;
33 41
34int cgit_query_has_symref = 0; 42int cgit_query_has_symref = 0;
35int cgit_query_has_sha1 = 0; 43int cgit_query_has_sha1 = 0;
36 44
37char *cgit_querystring = NULL; 45char *cgit_querystring = NULL;
38char *cgit_query_repo = NULL; 46char *cgit_query_repo = NULL;
39char *cgit_query_page = NULL; 47char *cgit_query_page = NULL;
40char *cgit_query_head = NULL; 48char *cgit_query_head = NULL;
41char *cgit_query_sha1 = NULL; 49char *cgit_query_sha1 = NULL;
42 50
43struct cacheitem cacheitem; 51struct cacheitem cacheitem;
44 52
45int cgit_parse_query(char *txt, configfn fn) 53int cgit_parse_query(char *txt, configfn fn)
46{ 54{
47 char *t, *value = NULL, c; 55 char *t, *value = NULL, c;
48 56
49 if (!txt) 57 if (!txt)
50 return 0; 58 return 0;
51 59
52 t = txt = xstrdup(txt); 60 t = txt = xstrdup(txt);
53 61
54 while((c=*t) != '\0') { 62 while((c=*t) != '\0') {
55 if (c=='=') { 63 if (c=='=') {
56 *t = '\0'; 64 *t = '\0';
57 value = t+1; 65 value = t+1;
58 } else if (c=='&') { 66 } else if (c=='&') {
59 *t = '\0'; 67 *t = '\0';
60 (*fn)(txt, value); 68 (*fn)(txt, value);
61 txt = t+1; 69 txt = t+1;
62 value = NULL; 70 value = NULL;
63 } 71 }
64 t++; 72 t++;
65 } 73 }
66 if (t!=txt) 74 if (t!=txt)
67 (*fn)(txt, value); 75 (*fn)(txt, value);
68 return 0; 76 return 0;
69} 77}
70 78
71void cgit_global_config_cb(const char *name, const char *value) 79void cgit_global_config_cb(const char *name, const char *value)
72{ 80{
73 if (!strcmp(name, "root")) 81 if (!strcmp(name, "root"))
74 cgit_root = xstrdup(value); 82 cgit_root = xstrdup(value);
75 else if (!strcmp(name, "root-title")) 83 else if (!strcmp(name, "root-title"))
76 cgit_root_title = xstrdup(value); 84 cgit_root_title = xstrdup(value);
77 else if (!strcmp(name, "css")) 85 else if (!strcmp(name, "css"))
78 cgit_css = xstrdup(value); 86 cgit_css = xstrdup(value);
79 else if (!strcmp(name, "logo")) 87 else if (!strcmp(name, "logo"))
80 cgit_logo = xstrdup(value); 88 cgit_logo = xstrdup(value);
81 else if (!strcmp(name, "logo-link")) 89 else if (!strcmp(name, "logo-link"))
82 cgit_logo_link = xstrdup(value); 90 cgit_logo_link = xstrdup(value);
83 else if (!strcmp(name, "virtual-root")) 91 else if (!strcmp(name, "virtual-root"))
84 cgit_virtual_root = xstrdup(value); 92 cgit_virtual_root = xstrdup(value);
85} 93}
86 94
87void cgit_repo_config_cb(const char *name, const char *value) 95void cgit_repo_config_cb(const char *name, const char *value)
88{ 96{
89 if (!strcmp(name, "name")) 97 if (!strcmp(name, "name"))
90 cgit_repo_name = xstrdup(value); 98 cgit_repo_name = xstrdup(value);
91 else if (!strcmp(name, "desc")) 99 else if (!strcmp(name, "desc"))
92 cgit_repo_desc = xstrdup(value); 100 cgit_repo_desc = xstrdup(value);
93 else if (!strcmp(name, "owner")) 101 else if (!strcmp(name, "owner"))
94 cgit_repo_owner = xstrdup(value); 102 cgit_repo_owner = xstrdup(value);
95} 103}
96 104
97void cgit_querystring_cb(const char *name, const char *value) 105void cgit_querystring_cb(const char *name, const char *value)
98{ 106{
99 if (!strcmp(name,"r")) 107 if (!strcmp(name,"r"))
100 cgit_query_repo = xstrdup(value); 108 cgit_query_repo = xstrdup(value);
101 else if (!strcmp(name, "p")) 109 else if (!strcmp(name, "p"))
102 cgit_query_page = xstrdup(value); 110 cgit_query_page = xstrdup(value);
103 else if (!strcmp(name, "h")) { 111 else if (!strcmp(name, "h")) {
104 cgit_query_head = xstrdup(value); 112 cgit_query_head = xstrdup(value);
105 cgit_query_has_symref = 1; 113 cgit_query_has_symref = 1;
106 } else if (!strcmp(name, "id")) { 114 } else if (!strcmp(name, "id")) {
107 cgit_query_sha1 = xstrdup(value); 115 cgit_query_sha1 = xstrdup(value);
108 cgit_query_has_sha1 = 1; 116 cgit_query_has_sha1 = 1;
109 } 117 }
110} 118}
111 119
112char *cgit_repourl(const char *reponame) 120char *cgit_repourl(const char *reponame)
113{ 121{
114 if (cgit_virtual_root) { 122 if (cgit_virtual_root) {
115 return fmt("%s/%s/", cgit_virtual_root, reponame); 123 return fmt("%s/%s/", cgit_virtual_root, reponame);
116 } else { 124 } else {
117 return fmt("?r=%s", reponame); 125 return fmt("?r=%s", reponame);
118 } 126 }
119} 127}
120 128
121char *cgit_pageurl(const char *reponame, const char *pagename, 129char *cgit_pageurl(const char *reponame, const char *pagename,
122 const char *query) 130 const char *query)
123{ 131{
124 if (cgit_virtual_root) { 132 if (cgit_virtual_root) {
125 return fmt("%s/%s/%s/?%s", cgit_virtual_root, reponame, 133 return fmt("%s/%s/%s/?%s", cgit_virtual_root, reponame,
126 pagename, query); 134 pagename, query);
127 } else { 135 } else {
128 return fmt("?r=%s&p=%s&%s", reponame, pagename, query); 136 return fmt("?r=%s&p=%s&%s", reponame, pagename, query);
129 } 137 }
130} 138}
131 139
132static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, 140static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1,
133 int flags, void *cb_data) 141 int flags, void *cb_data)
134{ 142{
135 struct commit *commit; 143 struct commit *commit;
136 char buf[256], *url; 144 char buf[256], *url;
137 145
138 commit = lookup_commit(sha1); 146 commit = lookup_commit(sha1);
139 if (commit && !parse_commit(commit)){ 147 if (commit && !parse_commit(commit)){
140 html("<tr><td>"); 148 html("<tr><td>");
141 url = cgit_pageurl(cgit_query_repo, "log", 149 url = cgit_pageurl(cgit_query_repo, "log",
142 fmt("h=%s", refname)); 150 fmt("h=%s", refname));
143 html_link_open(url, NULL, NULL); 151 html_link_open(url, NULL, NULL);
144 strncpy(buf, refname, sizeof(buf)); 152 strncpy(buf, refname, sizeof(buf));
145 html_txt(buf); 153 html_txt(buf);
146 html_link_close(); 154 html_link_close();
147 html("</td><td>"); 155 html("</td><td>");
148 pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, buf, 156 pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, buf,
149 sizeof(buf), 0, NULL, NULL, 0); 157 sizeof(buf), 0, NULL, NULL, 0);
150 html_txt(buf); 158 html_txt(buf);
151 html("</td></tr>\n"); 159 html("</td></tr>\n");
152 } else { 160 } else {
153 html("<tr><td>"); 161 html("<tr><td>");
154 html_txt(buf); 162 html_txt(buf);
155 html("</td><td>"); 163 html("</td><td>");
156 htmlf("*** bad ref %s", sha1_to_hex(sha1)); 164 htmlf("*** bad ref %s", sha1_to_hex(sha1));
157 html("</td></tr>\n"); 165 html("</td></tr>\n");
158 } 166 }
159 return 0; 167 return 0;
160} 168}
161 169
162/* Sun, 06 Nov 1994 08:49:37 GMT */ 170/* Sun, 06 Nov 1994 08:49:37 GMT */
163static char *http_date(time_t t) 171static char *http_date(time_t t)
164{ 172{
165 static char day[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 173 static char day[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
166 static char month[][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 174 static char month[][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
167 "Jul", "Aug", "Sep", "Oct", "Now", "Dec"}; 175 "Jul", "Aug", "Sep", "Oct", "Now", "Dec"};
168 struct tm *tm = gmtime(&t); 176 struct tm *tm = gmtime(&t);
169 return fmt("%s, %02d %s %04d %02d:%02d:%02d GMT", day[tm->tm_wday], 177 return fmt("%s, %02d %s %04d %02d:%02d:%02d GMT", day[tm->tm_wday],
170 tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year, 178 tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year,
171 tm->tm_hour, tm->tm_min, tm->tm_sec); 179 tm->tm_hour, tm->tm_min, tm->tm_sec);
172} 180}
173 181
174static int ttl_seconds(int ttl) 182static int ttl_seconds(int ttl)
175{ 183{
176 if (ttl<0) 184 if (ttl<0)
177 return 60 * 60 * 24 * 365; 185 return 60 * 60 * 24 * 365;
178 else 186 else
179 return ttl * 60; 187 return ttl * 60;
180} 188}
181 189
182static void cgit_print_docstart(char *title) 190static void cgit_print_docstart(char *title)
183{ 191{
184 html("Content-Type: text/html; charset=utf-8\n"); 192 html("Content-Type: text/html; charset=utf-8\n");
185 htmlf("Last-Modified: %s\n", http_date(cacheitem.st.st_mtime)); 193 htmlf("Last-Modified: %s\n", http_date(cacheitem.st.st_mtime));
186 htmlf("Expires: %s\n", http_date(cacheitem.st.st_mtime + 194 htmlf("Expires: %s\n", http_date(cacheitem.st.st_mtime +
187 ttl_seconds(cacheitem.ttl))); 195 ttl_seconds(cacheitem.ttl)));
188 html("\n"); 196 html("\n");
189 html(cgit_doctype); 197 html(cgit_doctype);
190 html("<html>\n"); 198 html("<html>\n");
191 html("<head>\n"); 199 html("<head>\n");
192 html("<title>"); 200 html("<title>");