summaryrefslogtreecommitdiffabout
path: root/cgit.c
authorLars Hjemli <hjemli@gmail.com>2007-05-15 22:14:51 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2007-05-15 22:16:00 (UTC)
commitb28b105ec172b258ae5d629381a5890697c2f938 (patch) (unidiff)
tree0673dc5ed94c8ce99c714d1204b6582f9ba96fc5 /cgit.c
parent47a81c77fdd017227632c4df9a0b7b135b8a738d (diff)
downloadcgit-b28b105ec172b258ae5d629381a5890697c2f938.zip
cgit-b28b105ec172b258ae5d629381a5890697c2f938.tar.gz
cgit-b28b105ec172b258ae5d629381a5890697c2f938.tar.bz2
Enable default value for head parameter
Pages which expect head to be specified in the querystring can now be given a default value, configurable per repository (via repo.defbranch, which defaults to "master"). Currently, only the log page actually works without parameters, but the defbranch is bound to be exploited. This also removes some dead code from shared.c Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'cgit.c') (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/cgit.c b/cgit.c
index 3c11ff0..b282a67 100644
--- a/cgit.c
+++ b/cgit.c
@@ -1,262 +1,265 @@
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
13 13
14static struct repoinfo *cgit_get_repoinfo(char *url) 14static struct repoinfo *cgit_get_repoinfo(char *url)
15{ 15{
16 int i; 16 int i;
17 struct repoinfo *repo; 17 struct repoinfo *repo;
18 18
19 for (i=0; i<cgit_repolist.count; i++) { 19 for (i=0; i<cgit_repolist.count; i++) {
20 repo = &cgit_repolist.repos[i]; 20 repo = &cgit_repolist.repos[i];
21 if (!strcmp(repo->url, url)) 21 if (!strcmp(repo->url, url))
22 return repo; 22 return repo;
23 } 23 }
24 return NULL; 24 return NULL;
25} 25}
26 26
27 27
28static int cgit_prepare_cache(struct cacheitem *item) 28static int cgit_prepare_cache(struct cacheitem *item)
29{ 29{
30 if (!cgit_query_repo) { 30 if (!cgit_query_repo) {
31 item->name = xstrdup(fmt("%s/index.html", cgit_cache_root)); 31 item->name = xstrdup(fmt("%s/index.html", cgit_cache_root));
32 item->ttl = cgit_cache_root_ttl; 32 item->ttl = cgit_cache_root_ttl;
33 return 1; 33 return 1;
34 } 34 }
35 cgit_repo = cgit_get_repoinfo(cgit_query_repo); 35 cgit_repo = cgit_get_repoinfo(cgit_query_repo);
36 if (!cgit_repo) { 36 if (!cgit_repo) {
37 char *title = fmt("%s - %s", cgit_root_title, "Bad request"); 37 char *title = fmt("%s - %s", cgit_root_title, "Bad request");
38 cgit_print_docstart(title, item); 38 cgit_print_docstart(title, item);
39 cgit_print_pageheader(title, 0); 39 cgit_print_pageheader(title, 0);
40 cgit_print_error(fmt("Unknown repo: %s", cgit_query_repo)); 40 cgit_print_error(fmt("Unknown repo: %s", cgit_query_repo));
41 cgit_print_docend(); 41 cgit_print_docend();
42 return 0; 42 return 0;
43 } 43 }
44 44
45 if (!cgit_query_page) { 45 if (!cgit_query_page) {
46 item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root, 46 item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root,
47 cgit_repo->url)); 47 cgit_repo->url));
48 item->ttl = cgit_cache_repo_ttl; 48 item->ttl = cgit_cache_repo_ttl;
49 } else { 49 } else {
50 item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root, 50 item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root,
51 cgit_repo->url, cgit_query_page, 51 cgit_repo->url, cgit_query_page,
52 cache_safe_filename(cgit_querystring))); 52 cache_safe_filename(cgit_querystring)));
53 if (cgit_query_has_symref) 53 if (cgit_query_has_symref)
54 item->ttl = cgit_cache_dynamic_ttl; 54 item->ttl = cgit_cache_dynamic_ttl;
55 else if (cgit_query_has_sha1) 55 else if (cgit_query_has_sha1)
56 item->ttl = cgit_cache_static_ttl; 56 item->ttl = cgit_cache_static_ttl;
57 else 57 else
58 item->ttl = cgit_cache_repo_ttl; 58 item->ttl = cgit_cache_repo_ttl;
59 } 59 }
60 return 1; 60 return 1;
61} 61}
62 62
63static void cgit_print_repo_page(struct cacheitem *item) 63static void cgit_print_repo_page(struct cacheitem *item)
64{ 64{
65 char *title; 65 char *title;
66 int show_search; 66 int show_search;
67 67
68 if (!cgit_query_head)
69 cgit_query_head = cgit_repo->defbranch;
70
68 if (chdir(cgit_repo->path)) { 71 if (chdir(cgit_repo->path)) {
69 title = fmt("%s - %s", cgit_root_title, "Bad request"); 72 title = fmt("%s - %s", cgit_root_title, "Bad request");
70 cgit_print_docstart(title, item); 73 cgit_print_docstart(title, item);
71 cgit_print_pageheader(title, 0); 74 cgit_print_pageheader(title, 0);
72 cgit_print_error(fmt("Unable to scan repository: %s", 75 cgit_print_error(fmt("Unable to scan repository: %s",
73 strerror(errno))); 76 strerror(errno)));
74 cgit_print_docend(); 77 cgit_print_docend();
75 return; 78 return;
76 } 79 }
77 80
78 title = fmt("%s - %s", cgit_repo->name, cgit_repo->desc); 81 title = fmt("%s - %s", cgit_repo->name, cgit_repo->desc);
79 show_search = 0; 82 show_search = 0;
80 setenv("GIT_DIR", cgit_repo->path, 1); 83 setenv("GIT_DIR", cgit_repo->path, 1);
81 84
82 if (cgit_query_page) { 85 if (cgit_query_page) {
83 if (cgit_repo->snapshots && !strcmp(cgit_query_page, "snapshot")) { 86 if (cgit_repo->snapshots && !strcmp(cgit_query_page, "snapshot")) {
84 cgit_print_snapshot(item, cgit_query_sha1, "zip", 87 cgit_print_snapshot(item, cgit_query_sha1, "zip",
85 cgit_repo->url, cgit_query_name); 88 cgit_repo->url, cgit_query_name);
86 return; 89 return;
87 } 90 }
88 if (!strcmp(cgit_query_page, "blob")) { 91 if (!strcmp(cgit_query_page, "blob")) {
89 cgit_print_blob(item, cgit_query_sha1, cgit_query_path); 92 cgit_print_blob(item, cgit_query_sha1, cgit_query_path);
90 return; 93 return;
91 } 94 }
92 } 95 }
93 96
94 if (cgit_query_page && !strcmp(cgit_query_page, "log")) 97 if (cgit_query_page && !strcmp(cgit_query_page, "log"))
95 show_search = 1; 98 show_search = 1;
96 99
97 cgit_print_docstart(title, item); 100 cgit_print_docstart(title, item);
98 101
99 102
100 if (!cgit_query_page) { 103 if (!cgit_query_page) {
101 cgit_print_pageheader("summary", show_search); 104 cgit_print_pageheader("summary", show_search);
102 cgit_print_summary(); 105 cgit_print_summary();
103 cgit_print_docend(); 106 cgit_print_docend();
104 return; 107 return;
105 } 108 }
106 109
107 cgit_print_pageheader(cgit_query_page, show_search); 110 cgit_print_pageheader(cgit_query_page, show_search);
108 111
109 if (!strcmp(cgit_query_page, "log")) { 112 if (!strcmp(cgit_query_page, "log")) {
110 cgit_print_log(cgit_query_head, cgit_query_ofs, 113 cgit_print_log(cgit_query_head, cgit_query_ofs,
111 cgit_max_commit_count, cgit_query_search, 114 cgit_max_commit_count, cgit_query_search,
112 cgit_query_path); 115 cgit_query_path);
113 } else if (!strcmp(cgit_query_page, "tree")) { 116 } else if (!strcmp(cgit_query_page, "tree")) {
114 cgit_print_tree(cgit_query_head, cgit_query_sha1, cgit_query_path); 117 cgit_print_tree(cgit_query_head, cgit_query_sha1, cgit_query_path);
115 } else if (!strcmp(cgit_query_page, "commit")) { 118 } else if (!strcmp(cgit_query_page, "commit")) {
116 cgit_print_commit(cgit_query_sha1); 119 cgit_print_commit(cgit_query_sha1);
117 } else if (!strcmp(cgit_query_page, "view")) { 120 } else if (!strcmp(cgit_query_page, "view")) {
118 cgit_print_view(cgit_query_sha1, cgit_query_path); 121 cgit_print_view(cgit_query_sha1, cgit_query_path);
119 } else if (!strcmp(cgit_query_page, "diff")) { 122 } else if (!strcmp(cgit_query_page, "diff")) {
120 cgit_print_diff(cgit_query_sha1, cgit_query_sha2, cgit_query_path); 123 cgit_print_diff(cgit_query_sha1, cgit_query_sha2, cgit_query_path);
121 } else { 124 } else {
122 cgit_print_error("Invalid request"); 125 cgit_print_error("Invalid request");
123 } 126 }
124 cgit_print_docend(); 127 cgit_print_docend();
125} 128}
126 129
127static void cgit_fill_cache(struct cacheitem *item, int use_cache) 130static void cgit_fill_cache(struct cacheitem *item, int use_cache)
128{ 131{
129 static char buf[PATH_MAX]; 132 static char buf[PATH_MAX];
130 int stdout2; 133 int stdout2;
131 134
132 getcwd(buf, sizeof(buf)); 135 getcwd(buf, sizeof(buf));
133 item->st.st_mtime = time(NULL); 136 item->st.st_mtime = time(NULL);
134 137
135 if (use_cache) { 138 if (use_cache) {
136 stdout2 = chk_positive(dup(STDOUT_FILENO), 139 stdout2 = chk_positive(dup(STDOUT_FILENO),
137 "Preserving STDOUT"); 140 "Preserving STDOUT");
138 chk_zero(close(STDOUT_FILENO), "Closing STDOUT"); 141 chk_zero(close(STDOUT_FILENO), "Closing STDOUT");
139 chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)"); 142 chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)");
140 } 143 }
141 144
142 if (cgit_query_repo) 145 if (cgit_query_repo)
143 cgit_print_repo_page(item); 146 cgit_print_repo_page(item);
144 else 147 else
145 cgit_print_repolist(item); 148 cgit_print_repolist(item);
146 149
147 if (use_cache) { 150 if (use_cache) {
148 chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT"); 151 chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT");
149 chk_positive(dup2(stdout2, STDOUT_FILENO), 152 chk_positive(dup2(stdout2, STDOUT_FILENO),
150 "Restoring original STDOUT"); 153 "Restoring original STDOUT");
151 chk_zero(close(stdout2), "Closing temporary STDOUT"); 154 chk_zero(close(stdout2), "Closing temporary STDOUT");
152 } 155 }
153 156
154 chdir(buf); 157 chdir(buf);
155} 158}
156 159
157static void cgit_check_cache(struct cacheitem *item) 160static void cgit_check_cache(struct cacheitem *item)
158{ 161{
159 int i = 0; 162 int i = 0;
160 163
161 top: 164 top:
162 if (++i > cgit_max_lock_attempts) { 165 if (++i > cgit_max_lock_attempts) {
163 die("cgit_refresh_cache: unable to lock %s: %s", 166 die("cgit_refresh_cache: unable to lock %s: %s",
164 item->name, strerror(errno)); 167 item->name, strerror(errno));
165 } 168 }
166 if (!cache_exist(item)) { 169 if (!cache_exist(item)) {
167 if (!cache_lock(item)) { 170 if (!cache_lock(item)) {
168 sleep(1); 171 sleep(1);
169 goto top; 172 goto top;
170 } 173 }
171 if (!cache_exist(item)) { 174 if (!cache_exist(item)) {
172 cgit_fill_cache(item, 1); 175 cgit_fill_cache(item, 1);
173 cache_unlock(item); 176 cache_unlock(item);
174 } else { 177 } else {
175 cache_cancel_lock(item); 178 cache_cancel_lock(item);
176 } 179 }
177 } else if (cache_expired(item) && cache_lock(item)) { 180 } else if (cache_expired(item) && cache_lock(item)) {
178 if (cache_expired(item)) { 181 if (cache_expired(item)) {
179 cgit_fill_cache(item, 1); 182 cgit_fill_cache(item, 1);
180 cache_unlock(item); 183 cache_unlock(item);
181 } else { 184 } else {
182 cache_cancel_lock(item); 185 cache_cancel_lock(item);
183 } 186 }
184 } 187 }
185} 188}
186 189
187static void cgit_print_cache(struct cacheitem *item) 190static void cgit_print_cache(struct cacheitem *item)
188{ 191{
189 static char buf[4096]; 192 static char buf[4096];
190 ssize_t i; 193 ssize_t i;
191 194
192 int fd = open(item->name, O_RDONLY); 195 int fd = open(item->name, O_RDONLY);
193 if (fd<0) 196 if (fd<0)
194 die("Unable to open cached file %s", item->name); 197 die("Unable to open cached file %s", item->name);
195 198
196 while((i=read(fd, buf, sizeof(buf))) > 0) 199 while((i=read(fd, buf, sizeof(buf))) > 0)
197 write(STDOUT_FILENO, buf, i); 200 write(STDOUT_FILENO, buf, i);
198 201
199 close(fd); 202 close(fd);
200} 203}
201 204
202static void cgit_parse_args(int argc, const char **argv) 205static void cgit_parse_args(int argc, const char **argv)
203{ 206{
204 int i; 207 int i;
205 208
206 for (i = 1; i < argc; i++) { 209 for (i = 1; i < argc; i++) {
207 if (!strncmp(argv[i], "--cache=", 8)) { 210 if (!strncmp(argv[i], "--cache=", 8)) {
208 cgit_cache_root = xstrdup(argv[i]+8); 211 cgit_cache_root = xstrdup(argv[i]+8);
209 } 212 }
210 if (!strcmp(argv[i], "--nocache")) { 213 if (!strcmp(argv[i], "--nocache")) {
211 cgit_nocache = 1; 214 cgit_nocache = 1;
212 } 215 }
213 if (!strncmp(argv[i], "--query=", 8)) { 216 if (!strncmp(argv[i], "--query=", 8)) {
214 cgit_querystring = xstrdup(argv[i]+8); 217 cgit_querystring = xstrdup(argv[i]+8);
215 } 218 }
216 if (!strncmp(argv[i], "--repo=", 7)) { 219 if (!strncmp(argv[i], "--repo=", 7)) {
217 cgit_query_repo = xstrdup(argv[i]+7); 220 cgit_query_repo = xstrdup(argv[i]+7);
218 } 221 }
219 if (!strncmp(argv[i], "--page=", 7)) { 222 if (!strncmp(argv[i], "--page=", 7)) {
220 cgit_query_page = xstrdup(argv[i]+7); 223 cgit_query_page = xstrdup(argv[i]+7);
221 } 224 }
222 if (!strncmp(argv[i], "--head=", 7)) { 225 if (!strncmp(argv[i], "--head=", 7)) {
223 cgit_query_head = xstrdup(argv[i]+7); 226 cgit_query_head = xstrdup(argv[i]+7);
224 cgit_query_has_symref = 1; 227 cgit_query_has_symref = 1;
225 } 228 }
226 if (!strncmp(argv[i], "--sha1=", 7)) { 229 if (!strncmp(argv[i], "--sha1=", 7)) {
227 cgit_query_sha1 = xstrdup(argv[i]+7); 230 cgit_query_sha1 = xstrdup(argv[i]+7);
228 cgit_query_has_sha1 = 1; 231 cgit_query_has_sha1 = 1;
229 } 232 }
230 if (!strncmp(argv[i], "--ofs=", 6)) { 233 if (!strncmp(argv[i], "--ofs=", 6)) {
231 cgit_query_ofs = atoi(argv[i]+6); 234 cgit_query_ofs = atoi(argv[i]+6);
232 } 235 }
233 } 236 }
234} 237}
235 238
236int main(int argc, const char **argv) 239int main(int argc, const char **argv)
237{ 240{
238 struct cacheitem item; 241 struct cacheitem item;
239 242
240 htmlfd = STDOUT_FILENO; 243 htmlfd = STDOUT_FILENO;
241 item.st.st_mtime = time(NULL); 244 item.st.st_mtime = time(NULL);
242 cgit_repolist.length = 0; 245 cgit_repolist.length = 0;
243 cgit_repolist.count = 0; 246 cgit_repolist.count = 0;
244 cgit_repolist.repos = NULL; 247 cgit_repolist.repos = NULL;
245 248
246 cgit_read_config(CGIT_CONFIG, cgit_global_config_cb); 249 cgit_read_config(CGIT_CONFIG, cgit_global_config_cb);
247 if (getenv("SCRIPT_NAME")) 250 if (getenv("SCRIPT_NAME"))
248 cgit_script_name = xstrdup(getenv("SCRIPT_NAME")); 251 cgit_script_name = xstrdup(getenv("SCRIPT_NAME"));
249 if (getenv("QUERY_STRING")) 252 if (getenv("QUERY_STRING"))
250 cgit_querystring = xstrdup(getenv("QUERY_STRING")); 253 cgit_querystring = xstrdup(getenv("QUERY_STRING"));
251 cgit_parse_args(argc, argv); 254 cgit_parse_args(argc, argv);
252 cgit_parse_query(cgit_querystring, cgit_querystring_cb); 255 cgit_parse_query(cgit_querystring, cgit_querystring_cb);
253 if (!cgit_prepare_cache(&item)) 256 if (!cgit_prepare_cache(&item))
254 return 0; 257 return 0;
255 if (cgit_nocache) { 258 if (cgit_nocache) {
256 cgit_fill_cache(&item, 0); 259 cgit_fill_cache(&item, 0);
257 } else { 260 } else {
258 cgit_check_cache(&item); 261 cgit_check_cache(&item);
259 cgit_print_cache(&item); 262 cgit_print_cache(&item);
260 } 263 }
261 return 0; 264 return 0;
262} 265}