X-Git-Url: https://gitweb.ps.run/ps-cgit/blobdiff_plain/25105d7ecaba474d4b7c364ebb586aac3dfc5abb..74620f12e4f7e91cb0a0b4ca731e07272d1b65f6:/cgit.c diff --git a/cgit.c b/cgit.c index 09c857c..b3ff512 100644 --- a/cgit.c +++ b/cgit.c @@ -1,14 +1,14 @@ -#include "cgit.h" - -static const char cgit_doctype[] = -"\n"; +/* cgit.c: cgi for the git scm + * + * Copyright (C) 2006 Lars Hjemli + * + * Licensed under GNU General Public License v2 + * (see COPYING for full license text) + */ -static const char cgit_error[] = -"
%s
"; +#include "cgit.h" -static const char cgit_lib_error[] = -"
%s: %s
"; +const char cgit_version[] = CGIT_VERSION; int htmlfd = 0; @@ -21,6 +21,7 @@ char *cgit_virtual_root = NULL; char *cgit_cache_root = "/var/cache/cgit"; +int cgit_max_lock_attempts = 5; int cgit_cache_root_ttl = 5; int cgit_cache_repo_ttl = 5; int cgit_cache_dynamic_ttl = 5; @@ -42,32 +43,6 @@ char *cgit_query_sha1 = NULL; struct cacheitem cacheitem; -int cgit_parse_query(char *txt, configfn fn) -{ - char *t, *value = NULL, c; - - if (!txt) - return 0; - - t = txt = xstrdup(txt); - - while((c=*t) != '\0') { - if (c=='=') { - *t = '\0'; - value = t+1; - } else if (c=='&') { - *t = '\0'; - (*fn)(txt, value); - txt = t+1; - value = NULL; - } - t++; - } - if (t!=txt) - (*fn)(txt, value); - return 0; -} - void cgit_global_config_cb(const char *name, const char *value) { if (!strcmp(name, "root")) @@ -109,26 +84,6 @@ void cgit_querystring_cb(const char *name, const char *value) } } -char *cgit_repourl(const char *reponame) -{ - if (cgit_virtual_root) { - return fmt("%s/%s/", cgit_virtual_root, reponame); - } else { - return fmt("?r=%s", reponame); - } -} - -char *cgit_pageurl(const char *reponame, const char *pagename, - const char *query) -{ - if (cgit_virtual_root) { - return fmt("%s/%s/%s/?%s", cgit_virtual_root, reponame, - pagename, query); - } else { - return fmt("?r=%s&p=%s&%s", reponame, pagename, query); - } -} - static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, int flags, void *cb_data) { @@ -159,110 +114,6 @@ static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, return 0; } -/* Sun, 06 Nov 1994 08:49:37 GMT */ -static char *http_date(time_t t) -{ - static char day[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; - static char month[][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Now", "Dec"}; - struct tm *tm = gmtime(&t); - return fmt("%s, %02d %s %04d %02d:%02d:%02d GMT", day[tm->tm_wday], - tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year, - tm->tm_hour, tm->tm_min, tm->tm_sec); -} - -static int ttl_seconds(int ttl) -{ - if (ttl<0) - return 60 * 60 * 24 * 365; - else - return ttl * 60; -} - -static void cgit_print_docstart(char *title) -{ - html("Content-Type: text/html; charset=utf-8\n"); - htmlf("Last-Modified: %s\n", http_date(cacheitem.st.st_mtime)); - htmlf("Expires: %s\n", http_date(cacheitem.st.st_mtime + - ttl_seconds(cacheitem.ttl))); - html("\n"); - html(cgit_doctype); - html("\n"); - html("\n"); - html(""); - html_txt(title); - html("\n"); - html("\n"); - html("\n"); - html("\n"); -} - -static void cgit_print_docend() -{ - html("\n\n"); -} - -static void cgit_print_pageheader(char *title) -{ - html(""); -} - -static void cgit_print_repolist() -{ - DIR *d; - struct dirent *de; - struct stat st; - char *name; - - chdir(cgit_root); - cgit_print_docstart(cgit_root_title); - cgit_print_pageheader(cgit_root_title); - - if (!(d = opendir("."))) { - htmlf(cgit_lib_error, "Unable to scan repository directory", - strerror(errno)); - cgit_print_docend(); - return; - } - - html("

Repositories

\n"); - html(""); - html("\n"); - while ((de = readdir(d)) != NULL) { - if (de->d_name[0] == '.') - continue; - if (stat(de->d_name, &st) < 0) - continue; - if (!S_ISDIR(st.st_mode)) - continue; - - cgit_repo_name = cgit_repo_desc = cgit_repo_owner = NULL; - name = fmt("%s/info/cgit", de->d_name); - if (cgit_read_config(name, cgit_repo_config_cb)) - continue; - - html("\n"); - } - closedir(d); - html("
NameDescriptionOwner
"); - html_link_open(cgit_repourl(de->d_name), NULL, NULL); - html_txt(cgit_repo_name); - html_link_close(); - html(""); - html_txt(cgit_repo_desc); - html(""); - html_txt(cgit_repo_owner); - html("
"); - cgit_print_docend(); -} - static void cgit_print_branches() { html(""); @@ -393,18 +244,18 @@ static void cgit_print_object(char *hex) unsigned long size; if (get_sha1_hex(hex, sha1)){ - htmlf(cgit_error, "Bad hex value"); + cgit_print_error(fmt("Bad hex value: %s", hex)); return; } if (sha1_object_info(sha1, type, NULL)){ - htmlf(cgit_error, "Bad object name"); + cgit_print_error("Bad object name"); return; } buf = read_sha1_file(sha1, type, &size); if (!buf) { - htmlf(cgit_error, "Error reading object"); + cgit_print_error("Error reading object"); return; } @@ -416,21 +267,21 @@ static void cgit_print_object(char *hex) html(""); } -static void cgit_print_repo_page() +static void cgit_print_repo_page(struct cacheitem *item) { if (chdir(fmt("%s/%s", cgit_root, cgit_query_repo)) || cgit_read_config("info/cgit", cgit_repo_config_cb)) { char *title = fmt("%s - %s", cgit_root_title, "Bad request"); - cgit_print_docstart(title); + cgit_print_docstart(title, item); cgit_print_pageheader(title); - htmlf(cgit_lib_error, "Unable to scan repository", - strerror(errno)); + cgit_print_error(fmt("Unable to scan repository: %s", + strerror(errno))); cgit_print_docend(); return; } setenv("GIT_DIR", fmt("%s/%s", cgit_root, cgit_query_repo), 1); char *title = fmt("%s - %s", cgit_repo_name, cgit_repo_desc); - cgit_print_docstart(title); + cgit_print_docstart(title, item); cgit_print_pageheader(title); if (!cgit_query_page) cgit_print_repo_summary(); @@ -447,27 +298,33 @@ static void cgit_fill_cache(struct cacheitem *item) htmlfd = item->fd; item->st.st_mtime = time(NULL); if (cgit_query_repo) - cgit_print_repo_page(); + cgit_print_repo_page(item); else - cgit_print_repolist(); + cgit_print_repolist(item); } static void cgit_refresh_cache(struct cacheitem *item) { + int i = 0; + + cache_prepare(item); top: - if (!cache_lookup(item)) { - if (cache_lock(item)) { - cgit_fill_cache(item); - cache_unlock(item); - } else { - sched_yield(); + if (++i > cgit_max_lock_attempts) { + die("cgit_refresh_cache: unable to lock %s: %s", + item->name, strerror(errno)); + } + if (!cache_exist(item)) { + if (!cache_lock(item)) { + sleep(1); goto top; } - } else if (cache_expired(item)) { - if (cache_lock(item)) { + if (!cache_exist(item)) cgit_fill_cache(item); - cache_unlock(item); - } + cache_unlock(item); + } else if (cache_expired(item) && cache_lock(item)) { + if (cache_expired(item)) + cgit_fill_cache(item); + cache_unlock(item); } }