summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/cgit.c b/cgit.c
index 763242a..6ec763f 100644
--- a/cgit.c
+++ b/cgit.c
@@ -251,208 +251,209 @@ static int prepare_repo_cmd(struct cgit_context *ctx)
251 tmp = fmt("Not a git repository: '%s'", ctx->repo->path); 251 tmp = fmt("Not a git repository: '%s'", ctx->repo->path);
252 ctx->repo = NULL; 252 ctx->repo = NULL;
253 cgit_print_http_headers(ctx); 253 cgit_print_http_headers(ctx);
254 cgit_print_docstart(ctx); 254 cgit_print_docstart(ctx);
255 cgit_print_pageheader(ctx); 255 cgit_print_pageheader(ctx);
256 cgit_print_error(tmp); 256 cgit_print_error(tmp);
257 cgit_print_docend(); 257 cgit_print_docend();
258 return 1; 258 return 1;
259 } 259 }
260 ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc); 260 ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc);
261 261
262 if (!ctx->qry.head) { 262 if (!ctx->qry.head) {
263 ctx->qry.head = xstrdup(find_default_branch(ctx->repo)); 263 ctx->qry.head = xstrdup(find_default_branch(ctx->repo));
264 ctx->repo->defbranch = ctx->qry.head; 264 ctx->repo->defbranch = ctx->qry.head;
265 } 265 }
266 266
267 if (!ctx->qry.head) { 267 if (!ctx->qry.head) {
268 cgit_print_http_headers(ctx); 268 cgit_print_http_headers(ctx);
269 cgit_print_docstart(ctx); 269 cgit_print_docstart(ctx);
270 cgit_print_pageheader(ctx); 270 cgit_print_pageheader(ctx);
271 cgit_print_error("Repository seems to be empty"); 271 cgit_print_error("Repository seems to be empty");
272 cgit_print_docend(); 272 cgit_print_docend();
273 return 1; 273 return 1;
274 } 274 }
275 275
276 if (get_sha1(ctx->qry.head, sha1)) { 276 if (get_sha1(ctx->qry.head, sha1)) {
277 tmp = xstrdup(ctx->qry.head); 277 tmp = xstrdup(ctx->qry.head);
278 ctx->qry.head = ctx->repo->defbranch; 278 ctx->qry.head = ctx->repo->defbranch;
279 cgit_print_http_headers(ctx); 279 cgit_print_http_headers(ctx);
280 cgit_print_docstart(ctx); 280 cgit_print_docstart(ctx);
281 cgit_print_pageheader(ctx); 281 cgit_print_pageheader(ctx);
282 cgit_print_error(fmt("Invalid branch: %s", tmp)); 282 cgit_print_error(fmt("Invalid branch: %s", tmp));
283 cgit_print_docend(); 283 cgit_print_docend();
284 return 1; 284 return 1;
285 } 285 }
286 return 0; 286 return 0;
287} 287}
288 288
289static void process_request(struct cgit_context *ctx) 289static void process_request(struct cgit_context *ctx)
290{ 290{
291 struct cgit_cmd *cmd; 291 struct cgit_cmd *cmd;
292 292
293 cmd = cgit_get_cmd(ctx); 293 cmd = cgit_get_cmd(ctx);
294 if (!cmd) { 294 if (!cmd) {
295 ctx->page.title = "cgit error"; 295 ctx->page.title = "cgit error";
296 ctx->repo = NULL; 296 ctx->repo = NULL;
297 cgit_print_http_headers(ctx); 297 cgit_print_http_headers(ctx);
298 cgit_print_docstart(ctx); 298 cgit_print_docstart(ctx);
299 cgit_print_pageheader(ctx); 299 cgit_print_pageheader(ctx);
300 cgit_print_error("Invalid request"); 300 cgit_print_error("Invalid request");
301 cgit_print_docend(); 301 cgit_print_docend();
302 return; 302 return;
303 } 303 }
304 304
305 if (cmd->want_repo && prepare_repo_cmd(ctx)) 305 if (cmd->want_repo && prepare_repo_cmd(ctx))
306 return; 306 return;
307 307
308 if (cmd->want_layout) { 308 if (cmd->want_layout) {
309 cgit_print_http_headers(ctx); 309 cgit_print_http_headers(ctx);
310 cgit_print_docstart(ctx); 310 cgit_print_docstart(ctx);
311 cgit_print_pageheader(ctx); 311 cgit_print_pageheader(ctx);
312 } 312 }
313 313
314 cmd->fn(ctx); 314 cmd->fn(ctx);
315 315
316 if (cmd->want_layout) 316 if (cmd->want_layout)
317 cgit_print_docend(); 317 cgit_print_docend();
318} 318}
319 319
320static long ttl_seconds(long ttl) 320static long ttl_seconds(long ttl)
321{ 321{
322 if (ttl<0) 322 if (ttl<0)
323 return 60 * 60 * 24 * 365; 323 return 60 * 60 * 24 * 365;
324 else 324 else
325 return ttl * 60; 325 return ttl * 60;
326} 326}
327 327
328static void cgit_fill_cache(struct cacheitem *item, int use_cache) 328static void cgit_fill_cache(struct cacheitem *item, int use_cache)
329{ 329{
330 int stdout2; 330 int stdout2;
331 331
332 if (use_cache) { 332 if (use_cache) {
333 stdout2 = chk_positive(dup(STDOUT_FILENO), 333 stdout2 = chk_positive(dup(STDOUT_FILENO),
334 "Preserving STDOUT"); 334 "Preserving STDOUT");
335 chk_zero(close(STDOUT_FILENO), "Closing STDOUT"); 335 chk_zero(close(STDOUT_FILENO), "Closing STDOUT");
336 chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)"); 336 chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)");
337 } 337 }
338 338
339 ctx.page.modified = time(NULL); 339 ctx.page.modified = time(NULL);
340 ctx.page.expires = ctx.page.modified + ttl_seconds(item->ttl); 340 ctx.page.expires = ctx.page.modified + ttl_seconds(item->ttl);
341 process_request(&ctx); 341 process_request(&ctx);
342 342
343 if (use_cache) { 343 if (use_cache) {
344 chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT"); 344 chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT");
345 chk_positive(dup2(stdout2, STDOUT_FILENO), 345 chk_positive(dup2(stdout2, STDOUT_FILENO),
346 "Restoring original STDOUT"); 346 "Restoring original STDOUT");
347 chk_zero(close(stdout2), "Closing temporary STDOUT"); 347 chk_zero(close(stdout2), "Closing temporary STDOUT");
348 } 348 }
349} 349}
350 350
351static void cgit_check_cache(struct cacheitem *item) 351static void cgit_check_cache(struct cacheitem *item)
352{ 352{
353 int i = 0; 353 int i = 0;
354 354
355 top: 355 top:
356 if (++i > ctx.cfg.max_lock_attempts) { 356 if (++i > ctx.cfg.max_lock_attempts) {
357 die("cgit_refresh_cache: unable to lock %s: %s", 357 die("cgit_refresh_cache: unable to lock %s: %s",
358 item->name, strerror(errno)); 358 item->name, strerror(errno));
359 } 359 }
360 if (!cache_exist(item)) { 360 if (!cache_exist(item)) {
361 if (!cache_lock(item)) { 361 if (!cache_lock(item)) {
362 sleep(1); 362 sleep(1);
363 goto top; 363 goto top;
364 } 364 }
365 if (!cache_exist(item)) { 365 if (!cache_exist(item)) {
366 cgit_fill_cache(item, 1); 366 cgit_fill_cache(item, 1);
367 cache_unlock(item); 367 cache_unlock(item);
368 } else { 368 } else {
369 cache_cancel_lock(item); 369 cache_cancel_lock(item);
370 } 370 }
371 } else if (cache_expired(item) && cache_lock(item)) { 371 } else if (cache_expired(item) && cache_lock(item)) {
372 if (cache_expired(item)) { 372 if (cache_expired(item)) {
373 cgit_fill_cache(item, 1); 373 cgit_fill_cache(item, 1);
374 cache_unlock(item); 374 cache_unlock(item);
375 } else { 375 } else {
376 cache_cancel_lock(item); 376 cache_cancel_lock(item);
377 } 377 }
378 } 378 }
379} 379}
380 380
381static void cgit_print_cache(struct cacheitem *item) 381static void cgit_print_cache(struct cacheitem *item)
382{ 382{
383 static char buf[4096]; 383 static char buf[4096];
384 ssize_t i; 384 ssize_t i;
385 385
386 int fd = open(item->name, O_RDONLY); 386 int fd = open(item->name, O_RDONLY);
387 if (fd<0) 387 if (fd<0)
388 die("Unable to open cached file %s", item->name); 388 die("Unable to open cached file %s", item->name);
389 389
390 while((i=read(fd, buf, sizeof(buf))) > 0) 390 while((i=read(fd, buf, sizeof(buf))) > 0)
391 write(STDOUT_FILENO, buf, i); 391 write(STDOUT_FILENO, buf, i);
392 392
393 close(fd); 393 close(fd);
394} 394}
395 395
396static void cgit_parse_args(int argc, const char **argv) 396static void cgit_parse_args(int argc, const char **argv)
397{ 397{
398 int i; 398 int i;
399 399
400 for (i = 1; i < argc; i++) { 400 for (i = 1; i < argc; i++) {
401 if (!strncmp(argv[i], "--cache=", 8)) { 401 if (!strncmp(argv[i], "--cache=", 8)) {
402 ctx.cfg.cache_root = xstrdup(argv[i]+8); 402 ctx.cfg.cache_root = xstrdup(argv[i]+8);
403 } 403 }
404 if (!strcmp(argv[i], "--nocache")) { 404 if (!strcmp(argv[i], "--nocache")) {
405 ctx.cfg.nocache = 1; 405 ctx.cfg.nocache = 1;
406 } 406 }
407 if (!strncmp(argv[i], "--query=", 8)) { 407 if (!strncmp(argv[i], "--query=", 8)) {
408 ctx.qry.raw = xstrdup(argv[i]+8); 408 ctx.qry.raw = xstrdup(argv[i]+8);
409 } 409 }
410 if (!strncmp(argv[i], "--repo=", 7)) { 410 if (!strncmp(argv[i], "--repo=", 7)) {
411 ctx.qry.repo = xstrdup(argv[i]+7); 411 ctx.qry.repo = xstrdup(argv[i]+7);
412 } 412 }
413 if (!strncmp(argv[i], "--page=", 7)) { 413 if (!strncmp(argv[i], "--page=", 7)) {
414 ctx.qry.page = xstrdup(argv[i]+7); 414 ctx.qry.page = xstrdup(argv[i]+7);
415 } 415 }
416 if (!strncmp(argv[i], "--head=", 7)) { 416 if (!strncmp(argv[i], "--head=", 7)) {
417 ctx.qry.head = xstrdup(argv[i]+7); 417 ctx.qry.head = xstrdup(argv[i]+7);
418 ctx.qry.has_symref = 1; 418 ctx.qry.has_symref = 1;
419 } 419 }
420 if (!strncmp(argv[i], "--sha1=", 7)) { 420 if (!strncmp(argv[i], "--sha1=", 7)) {
421 ctx.qry.sha1 = xstrdup(argv[i]+7); 421 ctx.qry.sha1 = xstrdup(argv[i]+7);
422 ctx.qry.has_sha1 = 1; 422 ctx.qry.has_sha1 = 1;
423 } 423 }
424 if (!strncmp(argv[i], "--ofs=", 6)) { 424 if (!strncmp(argv[i], "--ofs=", 6)) {
425 ctx.qry.ofs = atoi(argv[i]+6); 425 ctx.qry.ofs = atoi(argv[i]+6);
426 } 426 }
427 } 427 }
428} 428}
429 429
430int main(int argc, const char **argv) 430int main(int argc, const char **argv)
431{ 431{
432 struct cacheitem item; 432 struct cacheitem item;
433 const char *cgit_config_env = getenv("CGIT_CONFIG"); 433 const char *cgit_config_env = getenv("CGIT_CONFIG");
434 434
435 prepare_context(&ctx); 435 prepare_context(&ctx);
436 item.st.st_mtime = time(NULL); 436 item.st.st_mtime = time(NULL);
437 cgit_repolist.length = 0; 437 cgit_repolist.length = 0;
438 cgit_repolist.count = 0; 438 cgit_repolist.count = 0;
439 cgit_repolist.repos = NULL; 439 cgit_repolist.repos = NULL;
440 440
441 parse_configfile(cgit_config_env ? cgit_config_env : CGIT_CONFIG, 441 parse_configfile(cgit_config_env ? cgit_config_env : CGIT_CONFIG,
442 config_cb); 442 config_cb);
443 ctx.repo = NULL;
443 if (getenv("SCRIPT_NAME")) 444 if (getenv("SCRIPT_NAME"))
444 ctx.cfg.script_name = xstrdup(getenv("SCRIPT_NAME")); 445 ctx.cfg.script_name = xstrdup(getenv("SCRIPT_NAME"));
445 if (getenv("QUERY_STRING")) 446 if (getenv("QUERY_STRING"))
446 ctx.qry.raw = xstrdup(getenv("QUERY_STRING")); 447 ctx.qry.raw = xstrdup(getenv("QUERY_STRING"));
447 cgit_parse_args(argc, argv); 448 cgit_parse_args(argc, argv);
448 http_parse_querystring(ctx.qry.raw, querystring_cb); 449 http_parse_querystring(ctx.qry.raw, querystring_cb);
449 if (!cgit_prepare_cache(&item)) 450 if (!cgit_prepare_cache(&item))
450 return 0; 451 return 0;
451 if (ctx.cfg.nocache) { 452 if (ctx.cfg.nocache) {
452 cgit_fill_cache(&item, 0); 453 cgit_fill_cache(&item, 0);
453 } else { 454 } else {
454 cgit_check_cache(&item); 455 cgit_check_cache(&item);
455 cgit_print_cache(&item); 456 cgit_print_cache(&item);
456 } 457 }
457 return 0; 458 return 0;
458} 459}