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