summaryrefslogtreecommitdiffabout
path: root/cgit.c
authorLars Hjemli <hjemli@gmail.com>2006-12-11 08:57:58 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2006-12-11 08:57:58 (UTC)
commitf5069d88dff7a7ed2f4665904b03e906cca75a7c (patch) (unidiff)
tree4c9bfa3aaf931af4a345ffb9563b19825c38b628 /cgit.c
parent76827d8679d1d2bd46e8cddf7da2ce4178e1d676 (diff)
downloadcgit-f5069d88dff7a7ed2f4665904b03e906cca75a7c.zip
cgit-f5069d88dff7a7ed2f4665904b03e906cca75a7c.tar.gz
cgit-f5069d88dff7a7ed2f4665904b03e906cca75a7c.tar.bz2
Fix cache algorithm loophole
This closes the door for unneccessary calls to cgit_fill_cache(). Noticed by Linus. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'cgit.c') (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/cgit.c b/cgit.c
index 110face..7f14016 100644
--- a/cgit.c
+++ b/cgit.c
@@ -420,89 +420,89 @@ static void cgit_print_object(char *hex)
420 } 420 }
421 421
422 buf[size] = '\0'; 422 buf[size] = '\0';
423 html("<h2>Object view</h2>"); 423 html("<h2>Object view</h2>");
424 htmlf("sha1=%s<br/>type=%s<br/>size=%i<br/>", hex, type, size); 424 htmlf("sha1=%s<br/>type=%s<br/>size=%i<br/>", hex, type, size);
425 html("<pre>"); 425 html("<pre>");
426 html_txt(buf); 426 html_txt(buf);
427 html("</pre>"); 427 html("</pre>");
428} 428}
429 429
430static void cgit_print_repo_page() 430static void cgit_print_repo_page()
431{ 431{
432 if (chdir(fmt("%s/%s", cgit_root, cgit_query_repo)) || 432 if (chdir(fmt("%s/%s", cgit_root, cgit_query_repo)) ||
433 cgit_read_config("info/cgit", cgit_repo_config_cb)) { 433 cgit_read_config("info/cgit", cgit_repo_config_cb)) {
434 char *title = fmt("%s - %s", cgit_root_title, "Bad request"); 434 char *title = fmt("%s - %s", cgit_root_title, "Bad request");
435 cgit_print_docstart(title); 435 cgit_print_docstart(title);
436 cgit_print_pageheader(title); 436 cgit_print_pageheader(title);
437 htmlf(cgit_lib_error, "Unable to scan repository", 437 htmlf(cgit_lib_error, "Unable to scan repository",
438 strerror(errno)); 438 strerror(errno));
439 cgit_print_docend(); 439 cgit_print_docend();
440 return; 440 return;
441 } 441 }
442 setenv("GIT_DIR", fmt("%s/%s", cgit_root, cgit_query_repo), 1); 442 setenv("GIT_DIR", fmt("%s/%s", cgit_root, cgit_query_repo), 1);
443 char *title = fmt("%s - %s", cgit_repo_name, cgit_repo_desc); 443 char *title = fmt("%s - %s", cgit_repo_name, cgit_repo_desc);
444 cgit_print_docstart(title); 444 cgit_print_docstart(title);
445 cgit_print_pageheader(title); 445 cgit_print_pageheader(title);
446 if (!cgit_query_page) 446 if (!cgit_query_page)
447 cgit_print_repo_summary(); 447 cgit_print_repo_summary();
448 else if (!strcmp(cgit_query_page, "log")) { 448 else if (!strcmp(cgit_query_page, "log")) {
449 cgit_print_log(cgit_query_head, 0, 100); 449 cgit_print_log(cgit_query_head, 0, 100);
450 } else if (!strcmp(cgit_query_page, "view")) { 450 } else if (!strcmp(cgit_query_page, "view")) {
451 cgit_print_object(cgit_query_sha1); 451 cgit_print_object(cgit_query_sha1);
452 } 452 }
453 cgit_print_docend(); 453 cgit_print_docend();
454} 454}
455 455
456static void cgit_fill_cache(struct cacheitem *item) 456static void cgit_fill_cache(struct cacheitem *item)
457{ 457{
458 htmlfd = item->fd; 458 htmlfd = item->fd;
459 item->st.st_mtime = time(NULL); 459 item->st.st_mtime = time(NULL);
460 if (cgit_query_repo) 460 if (cgit_query_repo)
461 cgit_print_repo_page(); 461 cgit_print_repo_page();
462 else 462 else
463 cgit_print_repolist(); 463 cgit_print_repolist();
464} 464}
465 465
466static void cgit_refresh_cache(struct cacheitem *item) 466static void cgit_refresh_cache(struct cacheitem *item)
467{ 467{
468 cache_prepare(item);
468 top: 469 top:
469 if (!cache_lookup(item)) { 470 if (!cache_exist(item)) {
470 if (cache_lock(item)) { 471 if (!cache_lock(item)) {
471 cgit_fill_cache(item);
472 cache_unlock(item);
473 } else {
474 sched_yield(); 472 sched_yield();
475 goto top; 473 goto top;
476 } 474 }
477 } else if (cache_expired(item)) { 475 if (!cache_exist(item))
478 if (cache_lock(item)) {
479 cgit_fill_cache(item); 476 cgit_fill_cache(item);
480 cache_unlock(item); 477 cache_unlock(item);
481 } 478 } else if (cache_expired(item) && cache_lock(item)) {
479 if (cache_expired(item))
480 cgit_fill_cache(item);
481 cache_unlock(item);
482 } 482 }
483} 483}
484 484
485static void cgit_print_cache(struct cacheitem *item) 485static void cgit_print_cache(struct cacheitem *item)
486{ 486{
487 static char buf[4096]; 487 static char buf[4096];
488 ssize_t i; 488 ssize_t i;
489 489
490 int fd = open(item->name, O_RDONLY); 490 int fd = open(item->name, O_RDONLY);
491 if (fd<0) 491 if (fd<0)
492 die("Unable to open cached file %s", item->name); 492 die("Unable to open cached file %s", item->name);
493 493
494 while((i=read(fd, buf, sizeof(buf))) > 0) 494 while((i=read(fd, buf, sizeof(buf))) > 0)
495 write(STDOUT_FILENO, buf, i); 495 write(STDOUT_FILENO, buf, i);
496 496
497 close(fd); 497 close(fd);
498} 498}
499 499
500int main(int argc, const char **argv) 500int main(int argc, const char **argv)
501{ 501{
502 cgit_read_config("/etc/cgitrc", cgit_global_config_cb); 502 cgit_read_config("/etc/cgitrc", cgit_global_config_cb);
503 cgit_querystring = xstrdup(getenv("QUERY_STRING")); 503 cgit_querystring = xstrdup(getenv("QUERY_STRING"));
504 cgit_parse_query(cgit_querystring, cgit_querystring_cb); 504 cgit_parse_query(cgit_querystring, cgit_querystring_cb);
505 cgit_refresh_cache(&cacheitem); 505 cgit_refresh_cache(&cacheitem);
506 cgit_print_cache(&cacheitem); 506 cgit_print_cache(&cacheitem);
507 return 0; 507 return 0;
508} 508}