summaryrefslogtreecommitdiffabout
path: root/cgit.c
Unidiff
Diffstat (limited to 'cgit.c') (more/less context) (show whitespace changes)
-rw-r--r--cgit.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/cgit.c b/cgit.c
index b270fdc..2c933dc 100644
--- a/cgit.c
+++ b/cgit.c
@@ -62,62 +62,65 @@ int find_current_ref(const char *refname, const unsigned char *sha1,
62 if (!info->first_ref) 62 if (!info->first_ref)
63 info->first_ref = xstrdup(refname); 63 info->first_ref = xstrdup(refname);
64 return info->match; 64 return info->match;
65} 65}
66 66
67char *find_default_branch(struct cgit_repo *repo) 67char *find_default_branch(struct cgit_repo *repo)
68{ 68{
69 struct refmatch info; 69 struct refmatch info;
70 70
71 info.req_ref = repo->defbranch; 71 info.req_ref = repo->defbranch;
72 info.first_ref = NULL; 72 info.first_ref = NULL;
73 info.match = 0; 73 info.match = 0;
74 for_each_branch_ref(find_current_ref, &info); 74 for_each_branch_ref(find_current_ref, &info);
75 if (info.match) 75 if (info.match)
76 return info.req_ref; 76 return info.req_ref;
77 else 77 else
78 return info.first_ref; 78 return info.first_ref;
79} 79}
80 80
81static void cgit_print_repo_page(struct cacheitem *item) 81static void cgit_print_repo_page(struct cacheitem *item)
82{ 82{
83 char *title, *tmp; 83 char *title, *tmp;
84 int show_search; 84 int show_search;
85 unsigned char sha1[20]; 85 unsigned char sha1[20];
86 int nongit = 0;
86 87
87 if (chdir(ctx.repo->path)) { 88 setenv("GIT_DIR", ctx.repo->path, 1);
88 title = fmt("%s - %s", ctx.cfg.root_title, "Bad request"); 89 setup_git_directory_gently(&nongit);
90 if (nongit) {
91 title = fmt("%s - %s", ctx.cfg.root_title, "config error");
92 tmp = fmt("Not a git repository: '%s'", ctx.repo->path);
93 ctx.repo = NULL;
89 cgit_print_docstart(title, item); 94 cgit_print_docstart(title, item);
90 cgit_print_pageheader(title, 0); 95 cgit_print_pageheader(title, 0);
91 cgit_print_error(fmt("Unable to scan repository: %s", 96 cgit_print_error(tmp);
92 strerror(errno)));
93 cgit_print_docend(); 97 cgit_print_docend();
94 return; 98 return;
95 } 99 }
96 100
97 title = fmt("%s - %s", ctx.repo->name, ctx.repo->desc); 101 title = fmt("%s - %s", ctx.repo->name, ctx.repo->desc);
98 show_search = 0; 102 show_search = 0;
99 setenv("GIT_DIR", ctx.repo->path, 1);
100 103
101 if (!ctx.qry.head) { 104 if (!ctx.qry.head) {
102 ctx.qry.head = xstrdup(find_default_branch(ctx.repo)); 105 ctx.qry.head = xstrdup(find_default_branch(ctx.repo));
103 ctx.repo->defbranch = ctx.qry.head; 106 ctx.repo->defbranch = ctx.qry.head;
104 } 107 }
105 108
106 if (!ctx.qry.head) { 109 if (!ctx.qry.head) {
107 cgit_print_docstart(title, item); 110 cgit_print_docstart(title, item);
108 cgit_print_pageheader(title, 0); 111 cgit_print_pageheader(title, 0);
109 cgit_print_error("Repository seems to be empty"); 112 cgit_print_error("Repository seems to be empty");
110 cgit_print_docend(); 113 cgit_print_docend();
111 return; 114 return;
112 } 115 }
113 116
114 if (get_sha1(ctx.qry.head, sha1)) { 117 if (get_sha1(ctx.qry.head, sha1)) {
115 tmp = xstrdup(ctx.qry.head); 118 tmp = xstrdup(ctx.qry.head);
116 ctx.qry.head = ctx.repo->defbranch; 119 ctx.qry.head = ctx.repo->defbranch;
117 cgit_print_docstart(title, item); 120 cgit_print_docstart(title, item);
118 cgit_print_pageheader(title, 0); 121 cgit_print_pageheader(title, 0);
119 cgit_print_error(fmt("Invalid branch: %s", tmp)); 122 cgit_print_error(fmt("Invalid branch: %s", tmp));
120 cgit_print_docend(); 123 cgit_print_docend();
121 return; 124 return;
122 } 125 }
123 126
@@ -158,74 +161,70 @@ static void cgit_print_repo_page(struct cacheitem *item)
158 break; 161 break;
159 case CMD_TREE: 162 case CMD_TREE:
160 cgit_print_tree(ctx.qry.sha1, ctx.qry.path); 163 cgit_print_tree(ctx.qry.sha1, ctx.qry.path);
161 break; 164 break;
162 case CMD_COMMIT: 165 case CMD_COMMIT:
163 cgit_print_commit(ctx.qry.sha1); 166 cgit_print_commit(ctx.qry.sha1);
164 break; 167 break;
165 case CMD_REFS: 168 case CMD_REFS:
166 cgit_print_refs(); 169 cgit_print_refs();
167 break; 170 break;
168 case CMD_TAG: 171 case CMD_TAG:
169 cgit_print_tag(ctx.qry.sha1); 172 cgit_print_tag(ctx.qry.sha1);
170 break; 173 break;
171 case CMD_DIFF: 174 case CMD_DIFF:
172 cgit_print_diff(ctx.qry.sha1, ctx.qry.sha2, ctx.qry.path); 175 cgit_print_diff(ctx.qry.sha1, ctx.qry.sha2, ctx.qry.path);
173 break; 176 break;
174 default: 177 default:
175 cgit_print_error("Invalid request"); 178 cgit_print_error("Invalid request");
176 } 179 }
177 cgit_print_docend(); 180 cgit_print_docend();
178} 181}
179 182
180static void cgit_fill_cache(struct cacheitem *item, int use_cache) 183static void cgit_fill_cache(struct cacheitem *item, int use_cache)
181{ 184{
182 static char buf[PATH_MAX];
183 int stdout2; 185 int stdout2;
184 186
185 getcwd(buf, sizeof(buf));
186 item->st.st_mtime = time(NULL); 187 item->st.st_mtime = time(NULL);
187 188
188 if (use_cache) { 189 if (use_cache) {
189 stdout2 = chk_positive(dup(STDOUT_FILENO), 190 stdout2 = chk_positive(dup(STDOUT_FILENO),
190 "Preserving STDOUT"); 191 "Preserving STDOUT");
191 chk_zero(close(STDOUT_FILENO), "Closing STDOUT"); 192 chk_zero(close(STDOUT_FILENO), "Closing STDOUT");
192 chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)"); 193 chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)");
193 } 194 }
194 195
195 if (ctx.repo) 196 if (ctx.repo)
196 cgit_print_repo_page(item); 197 cgit_print_repo_page(item);
197 else 198 else
198 cgit_print_repolist(item); 199 cgit_print_repolist(item);
199 200
200 if (use_cache) { 201 if (use_cache) {
201 chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT"); 202 chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT");
202 chk_positive(dup2(stdout2, STDOUT_FILENO), 203 chk_positive(dup2(stdout2, STDOUT_FILENO),
203 "Restoring original STDOUT"); 204 "Restoring original STDOUT");
204 chk_zero(close(stdout2), "Closing temporary STDOUT"); 205 chk_zero(close(stdout2), "Closing temporary STDOUT");
205 } 206 }
206
207 chdir(buf);
208} 207}
209 208
210static void cgit_check_cache(struct cacheitem *item) 209static void cgit_check_cache(struct cacheitem *item)
211{ 210{
212 int i = 0; 211 int i = 0;
213 212
214 top: 213 top:
215 if (++i > ctx.cfg.max_lock_attempts) { 214 if (++i > ctx.cfg.max_lock_attempts) {
216 die("cgit_refresh_cache: unable to lock %s: %s", 215 die("cgit_refresh_cache: unable to lock %s: %s",
217 item->name, strerror(errno)); 216 item->name, strerror(errno));
218 } 217 }
219 if (!cache_exist(item)) { 218 if (!cache_exist(item)) {
220 if (!cache_lock(item)) { 219 if (!cache_lock(item)) {
221 sleep(1); 220 sleep(1);
222 goto top; 221 goto top;
223 } 222 }
224 if (!cache_exist(item)) { 223 if (!cache_exist(item)) {
225 cgit_fill_cache(item, 1); 224 cgit_fill_cache(item, 1);
226 cache_unlock(item); 225 cache_unlock(item);
227 } else { 226 } else {
228 cache_cancel_lock(item); 227 cache_cancel_lock(item);
229 } 228 }
230 } else if (cache_expired(item) && cache_lock(item)) { 229 } else if (cache_expired(item) && cache_lock(item)) {
231 if (cache_expired(item)) { 230 if (cache_expired(item)) {