|
diff --git a/cgit.c b/cgit.c index 5438fa1..b3ff512 100644 --- a/ cgit.c+++ b/ cgit.c |
|
@@ -23,227 +23,158 @@ char *cgit_cache_root = "/var/cache/cgit"; |
23 | |
23 | |
24 | int cgit_max_lock_attempts = 5; |
24 | int cgit_max_lock_attempts = 5; |
25 | int cgit_cache_root_ttl = 5; |
25 | int cgit_cache_root_ttl = 5; |
26 | int cgit_cache_repo_ttl = 5; |
26 | int cgit_cache_repo_ttl = 5; |
27 | int cgit_cache_dynamic_ttl = 5; |
27 | int cgit_cache_dynamic_ttl = 5; |
28 | int cgit_cache_static_ttl = -1; |
28 | int cgit_cache_static_ttl = -1; |
29 | int cgit_cache_max_create_time = 5; |
29 | int cgit_cache_max_create_time = 5; |
30 | |
30 | |
31 | char *cgit_repo_name = NULL; |
31 | char *cgit_repo_name = NULL; |
32 | char *cgit_repo_desc = NULL; |
32 | char *cgit_repo_desc = NULL; |
33 | char *cgit_repo_owner = NULL; |
33 | char *cgit_repo_owner = NULL; |
34 | |
34 | |
35 | int cgit_query_has_symref = 0; |
35 | int cgit_query_has_symref = 0; |
36 | int cgit_query_has_sha1 = 0; |
36 | int cgit_query_has_sha1 = 0; |
37 | |
37 | |
38 | char *cgit_querystring = NULL; |
38 | char *cgit_querystring = NULL; |
39 | char *cgit_query_repo = NULL; |
39 | char *cgit_query_repo = NULL; |
40 | char *cgit_query_page = NULL; |
40 | char *cgit_query_page = NULL; |
41 | char *cgit_query_head = NULL; |
41 | char *cgit_query_head = NULL; |
42 | char *cgit_query_sha1 = NULL; |
42 | char *cgit_query_sha1 = NULL; |
43 | |
43 | |
44 | struct cacheitem cacheitem; |
44 | struct cacheitem cacheitem; |
45 | |
45 | |
46 | void cgit_global_config_cb(const char *name, const char *value) |
46 | void cgit_global_config_cb(const char *name, const char *value) |
47 | { |
47 | { |
48 | if (!strcmp(name, "root")) |
48 | if (!strcmp(name, "root")) |
49 | cgit_root = xstrdup(value); |
49 | cgit_root = xstrdup(value); |
50 | else if (!strcmp(name, "root-title")) |
50 | else if (!strcmp(name, "root-title")) |
51 | cgit_root_title = xstrdup(value); |
51 | cgit_root_title = xstrdup(value); |
52 | else if (!strcmp(name, "css")) |
52 | else if (!strcmp(name, "css")) |
53 | cgit_css = xstrdup(value); |
53 | cgit_css = xstrdup(value); |
54 | else if (!strcmp(name, "logo")) |
54 | else if (!strcmp(name, "logo")) |
55 | cgit_logo = xstrdup(value); |
55 | cgit_logo = xstrdup(value); |
56 | else if (!strcmp(name, "logo-link")) |
56 | else if (!strcmp(name, "logo-link")) |
57 | cgit_logo_link = xstrdup(value); |
57 | cgit_logo_link = xstrdup(value); |
58 | else if (!strcmp(name, "virtual-root")) |
58 | else if (!strcmp(name, "virtual-root")) |
59 | cgit_virtual_root = xstrdup(value); |
59 | cgit_virtual_root = xstrdup(value); |
60 | } |
60 | } |
61 | |
61 | |
62 | void cgit_repo_config_cb(const char *name, const char *value) |
62 | void cgit_repo_config_cb(const char *name, const char *value) |
63 | { |
63 | { |
64 | if (!strcmp(name, "name")) |
64 | if (!strcmp(name, "name")) |
65 | cgit_repo_name = xstrdup(value); |
65 | cgit_repo_name = xstrdup(value); |
66 | else if (!strcmp(name, "desc")) |
66 | else if (!strcmp(name, "desc")) |
67 | cgit_repo_desc = xstrdup(value); |
67 | cgit_repo_desc = xstrdup(value); |
68 | else if (!strcmp(name, "owner")) |
68 | else if (!strcmp(name, "owner")) |
69 | cgit_repo_owner = xstrdup(value); |
69 | cgit_repo_owner = xstrdup(value); |
70 | } |
70 | } |
71 | |
71 | |
72 | void cgit_querystring_cb(const char *name, const char *value) |
72 | void cgit_querystring_cb(const char *name, const char *value) |
73 | { |
73 | { |
74 | if (!strcmp(name,"r")) |
74 | if (!strcmp(name,"r")) |
75 | cgit_query_repo = xstrdup(value); |
75 | cgit_query_repo = xstrdup(value); |
76 | else if (!strcmp(name, "p")) |
76 | else if (!strcmp(name, "p")) |
77 | cgit_query_page = xstrdup(value); |
77 | cgit_query_page = xstrdup(value); |
78 | else if (!strcmp(name, "h")) { |
78 | else if (!strcmp(name, "h")) { |
79 | cgit_query_head = xstrdup(value); |
79 | cgit_query_head = xstrdup(value); |
80 | cgit_query_has_symref = 1; |
80 | cgit_query_has_symref = 1; |
81 | } else if (!strcmp(name, "id")) { |
81 | } else if (!strcmp(name, "id")) { |
82 | cgit_query_sha1 = xstrdup(value); |
82 | cgit_query_sha1 = xstrdup(value); |
83 | cgit_query_has_sha1 = 1; |
83 | cgit_query_has_sha1 = 1; |
84 | } |
84 | } |
85 | } |
85 | } |
86 | |
86 | |
87 | char *cgit_repourl(const char *reponame) |
| |
88 | { |
| |
89 | if (cgit_virtual_root) { |
| |
90 | return fmt("%s/%s/", cgit_virtual_root, reponame); |
| |
91 | } else { |
| |
92 | return fmt("?r=%s", reponame); |
| |
93 | } |
| |
94 | } |
| |
95 | |
| |
96 | char *cgit_pageurl(const char *reponame, const char *pagename, |
| |
97 | const char *query) |
| |
98 | { |
| |
99 | if (cgit_virtual_root) { |
| |
100 | return fmt("%s/%s/%s/?%s", cgit_virtual_root, reponame, |
| |
101 | pagename, query); |
| |
102 | } else { |
| |
103 | return fmt("?r=%s&p=%s&%s", reponame, pagename, query); |
| |
104 | } |
| |
105 | } |
| |
106 | |
| |
107 | static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, |
87 | static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, |
108 | int flags, void *cb_data) |
88 | int flags, void *cb_data) |
109 | { |
89 | { |
110 | struct commit *commit; |
90 | struct commit *commit; |
111 | char buf[256], *url; |
91 | char buf[256], *url; |
112 | |
92 | |
113 | commit = lookup_commit(sha1); |
93 | commit = lookup_commit(sha1); |
114 | if (commit && !parse_commit(commit)){ |
94 | if (commit && !parse_commit(commit)){ |
115 | html("<tr><td>"); |
95 | html("<tr><td>"); |
116 | url = cgit_pageurl(cgit_query_repo, "log", |
96 | url = cgit_pageurl(cgit_query_repo, "log", |
117 | fmt("h=%s", refname)); |
97 | fmt("h=%s", refname)); |
118 | html_link_open(url, NULL, NULL); |
98 | html_link_open(url, NULL, NULL); |
119 | strncpy(buf, refname, sizeof(buf)); |
99 | strncpy(buf, refname, sizeof(buf)); |
120 | html_txt(buf); |
100 | html_txt(buf); |
121 | html_link_close(); |
101 | html_link_close(); |
122 | html("</td><td>"); |
102 | html("</td><td>"); |
123 | pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, buf, |
103 | pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, buf, |
124 | sizeof(buf), 0, NULL, NULL, 0); |
104 | sizeof(buf), 0, NULL, NULL, 0); |
125 | html_txt(buf); |
105 | html_txt(buf); |
126 | html("</td></tr>\n"); |
106 | html("</td></tr>\n"); |
127 | } else { |
107 | } else { |
128 | html("<tr><td>"); |
108 | html("<tr><td>"); |
129 | html_txt(buf); |
109 | html_txt(buf); |
130 | html("</td><td>"); |
110 | html("</td><td>"); |
131 | htmlf("*** bad ref %s", sha1_to_hex(sha1)); |
111 | htmlf("*** bad ref %s", sha1_to_hex(sha1)); |
132 | html("</td></tr>\n"); |
112 | html("</td></tr>\n"); |
133 | } |
113 | } |
134 | return 0; |
114 | return 0; |
135 | } |
115 | } |
136 | |
116 | |
137 | static void cgit_print_repolist(struct cacheitem *item) |
| |
138 | { |
| |
139 | DIR *d; |
| |
140 | struct dirent *de; |
| |
141 | struct stat st; |
| |
142 | char *name; |
| |
143 | |
| |
144 | chdir(cgit_root); |
| |
145 | cgit_print_docstart(cgit_root_title, item); |
| |
146 | cgit_print_pageheader(cgit_root_title); |
| |
147 | |
| |
148 | if (!(d = opendir("."))) { |
| |
149 | cgit_print_error(fmt("Unable to scan repository directory: %s", |
| |
150 | strerror(errno))); |
| |
151 | cgit_print_docend(); |
| |
152 | return; |
| |
153 | } |
| |
154 | |
| |
155 | html("<h2>Repositories</h2>\n"); |
| |
156 | html("<table class='list'>"); |
| |
157 | html("<tr><th>Name</th><th>Description</th><th>Owner</th></tr>\n"); |
| |
158 | while ((de = readdir(d)) != NULL) { |
| |
159 | if (de->d_name[0] == '.') |
| |
160 | continue; |
| |
161 | if (stat(de->d_name, &st) < 0) |
| |
162 | continue; |
| |
163 | if (!S_ISDIR(st.st_mode)) |
| |
164 | continue; |
| |
165 | |
| |
166 | cgit_repo_name = cgit_repo_desc = cgit_repo_owner = NULL; |
| |
167 | name = fmt("%s/info/cgit", de->d_name); |
| |
168 | if (cgit_read_config(name, cgit_repo_config_cb)) |
| |
169 | continue; |
| |
170 | |
| |
171 | html("<tr><td>"); |
| |
172 | html_link_open(cgit_repourl(de->d_name), NULL, NULL); |
| |
173 | html_txt(cgit_repo_name); |
| |
174 | html_link_close(); |
| |
175 | html("</td><td>"); |
| |
176 | html_txt(cgit_repo_desc); |
| |
177 | html("</td><td>"); |
| |
178 | html_txt(cgit_repo_owner); |
| |
179 | html("</td></tr>\n"); |
| |
180 | } |
| |
181 | closedir(d); |
| |
182 | html("</table>"); |
| |
183 | cgit_print_docend(); |
| |
184 | } |
| |
185 | |
| |
186 | static void cgit_print_branches() |
117 | static void cgit_print_branches() |
187 | { |
118 | { |
188 | html("<table class='list'>"); |
119 | html("<table class='list'>"); |
189 | html("<tr><th>Branch name</th><th>Head commit</th></tr>\n"); |
120 | html("<tr><th>Branch name</th><th>Head commit</th></tr>\n"); |
190 | for_each_branch_ref(cgit_print_branch_cb, NULL); |
121 | for_each_branch_ref(cgit_print_branch_cb, NULL); |
191 | html("</table>"); |
122 | html("</table>"); |
192 | } |
123 | } |
193 | |
124 | |
194 | static int get_one_line(char *txt) |
125 | static int get_one_line(char *txt) |
195 | { |
126 | { |
196 | char *t; |
127 | char *t; |
197 | |
128 | |
198 | for(t=txt; *t != '\n' && t != '\0'; t++) |
129 | for(t=txt; *t != '\n' && t != '\0'; t++) |
199 | ; |
130 | ; |
200 | *t = '\0'; |
131 | *t = '\0'; |
201 | return t-txt-1; |
132 | return t-txt-1; |
202 | } |
133 | } |
203 | |
134 | |
204 | static void cgit_print_commit_shortlog(struct commit *commit) |
135 | static void cgit_print_commit_shortlog(struct commit *commit) |
205 | { |
136 | { |
206 | char *h, *t, *p; |
137 | char *h, *t, *p; |
207 | char *tree = NULL, *author = NULL, *subject = NULL; |
138 | char *tree = NULL, *author = NULL, *subject = NULL; |
208 | int len; |
139 | int len; |
209 | time_t sec; |
140 | time_t sec; |
210 | struct tm *time; |
141 | struct tm *time; |
211 | char buf[32]; |
142 | char buf[32]; |
212 | |
143 | |
213 | h = t = commit->buffer; |
144 | h = t = commit->buffer; |
214 | |
145 | |
215 | if (strncmp(h, "tree ", 5)) |
146 | if (strncmp(h, "tree ", 5)) |
216 | die("Bad commit format: %s", |
147 | die("Bad commit format: %s", |
217 | sha1_to_hex(commit->object.sha1)); |
148 | sha1_to_hex(commit->object.sha1)); |
218 | |
149 | |
219 | len = get_one_line(h); |
150 | len = get_one_line(h); |
220 | tree = h+5; |
151 | tree = h+5; |
221 | h += len + 2; |
152 | h += len + 2; |
222 | |
153 | |
223 | while (!strncmp(h, "parent ", 7)) |
154 | while (!strncmp(h, "parent ", 7)) |
224 | h += get_one_line(h) + 2; |
155 | h += get_one_line(h) + 2; |
225 | |
156 | |
226 | if (!strncmp(h, "author ", 7)) { |
157 | if (!strncmp(h, "author ", 7)) { |
227 | author = h+7; |
158 | author = h+7; |
228 | h += get_one_line(h) + 2; |
159 | h += get_one_line(h) + 2; |
229 | t = author; |
160 | t = author; |
230 | while(t!=h && *t!='<') |
161 | while(t!=h && *t!='<') |
231 | t++; |
162 | t++; |
232 | *t='\0'; |
163 | *t='\0'; |
233 | p = t; |
164 | p = t; |
234 | while(--t!=author && *t==' ') |
165 | while(--t!=author && *t==' ') |
235 | *t='\0'; |
166 | *t='\0'; |
236 | while(++p!=h && *p!='>') |
167 | while(++p!=h && *p!='>') |
237 | ; |
168 | ; |
238 | while(++p!=h && !isdigit(*p)) |
169 | while(++p!=h && !isdigit(*p)) |
239 | ; |
170 | ; |
240 | |
171 | |
241 | t = p; |
172 | t = p; |
242 | while(++p && isdigit(*p)) |
173 | while(++p && isdigit(*p)) |
243 | ; |
174 | ; |
244 | *p = '\0'; |
175 | *p = '\0'; |
245 | sec = atoi(t); |
176 | sec = atoi(t); |
246 | time = gmtime(&sec); |
177 | time = gmtime(&sec); |
247 | } |
178 | } |
248 | |
179 | |
249 | while((len = get_one_line(h)) > 0) |
180 | while((len = get_one_line(h)) > 0) |
|