diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | README | 13 | ||||
-rw-r--r-- | cache.c | 28 | ||||
-rw-r--r-- | cgit.c | 23 | ||||
-rw-r--r-- | cgit.h | 1 | ||||
-rw-r--r-- | cgit.mk | 44 | ||||
-rw-r--r-- | cgitrc.5.txt | 42 | ||||
-rw-r--r-- | cmd.c | 2 | ||||
-rw-r--r-- | filters/simple-authentication.lua | 2 | ||||
-rwxr-xr-x | gen-version.sh | 2 | ||||
m--------- | git | 0 | ||||
-rw-r--r-- | shared.c | 1 | ||||
-rwxr-xr-x | tests/setup.sh | 12 | ||||
-rwxr-xr-x | tests/t0111-filter.sh | 7 | ||||
-rw-r--r-- | ui-refs.c | 16 | ||||
-rw-r--r-- | ui-snapshot.c | 2 | ||||
-rw-r--r-- | ui-snapshot.h | 2 |
17 files changed, 133 insertions, 69 deletions
@@ -1,6 +1,6 @@ all:: -CGIT_VERSION = v0.10 +CGIT_VERSION = v0.10.1 CGIT_SCRIPT_NAME = cgit.cgi CGIT_SCRIPT_PATH = /var/www/htdocs/cgit CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH) @@ -14,7 +14,7 @@ htmldir = $(docdir) pdfdir = $(docdir) mandir = $(prefix)/share/man SHA1_HEADER = <openssl/sha.h> -GIT_VER = 1.8.5 +GIT_VER = 1.9.0 GIT_URL = https://git-core.googlecode.com/files/git-$(GIT_VER).tar.gz INSTALL = install COPYTREE = cp -r @@ -29,6 +29,7 @@ DOC_PDF = $(patsubst %.txt,%.pdf,$(MAN_TXT)) # j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t). # some C compilers supported these specifiers prior to C99 as an extension. # +# Define HAVE_LINUX_SENDFILE to use sendfile() #-include config.mak @@ -38,14 +38,11 @@ If you'd like to compile without Lua support, you may use: And if you'd like to specify a Lua implementation, you may use: - $ make LUA_IMPLEMENTATION=JIT + $ make LUA_PKGCONFIG=lua5.1 -for using the LuaJIT project. Or: - - $ make LUA_IMPLEMENTATION=VANILLA - -for the mainline Lua project. If you specify neither implementation, it will -be auto-detected, preferring LuaJIT if both are present. +If this is not specified, the Lua implementation will be auto-detected, +preferring LuaJIT if many are present. Acceptable values are generally "lua", +"luajit", "lua5.1", and "lua5.2". Dependencies @@ -54,7 +51,7 @@ Dependencies * libzip * libcrypto (OpenSSL) * libssl (OpenSSL) -* optional: luajit or lua +* optional: luajit or lua, most reliably used when pkg-config is available Apache configuration -------------------- @@ -13,6 +13,9 @@ * */ +#ifdef HAVE_LINUX_SENDFILE +#include <sys/sendfile.h> +#endif #include "cgit.h" #include "cache.h" #include "html.h" @@ -30,7 +33,6 @@ struct cache_slot { const char *lock_name; int match; struct stat cache_st; - struct stat lock_st; int bufsize; char buf[CACHE_BUFSIZE]; }; @@ -81,6 +83,23 @@ static int close_slot(struct cache_slot *slot) /* Print the content of the active cache slot (but skip the key). */ static int print_slot(struct cache_slot *slot) { +#ifdef HAVE_LINUX_SENDFILE + off_t start_off; + int ret; + + start_off = slot->keylen + 1; + + do { + ret = sendfile(STDOUT_FILENO, slot->cache_fd, &start_off, + slot->cache_st.st_size - start_off); + if (ret < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + return errno; + } + return 0; + } while (1); +#else ssize_t i, j; i = lseek(slot->cache_fd, slot->keylen + 1, SEEK_SET); @@ -97,6 +116,7 @@ static int print_slot(struct cache_slot *slot) return errno; else return 0; +#endif } /* Check if the slot has expired */ @@ -188,6 +208,10 @@ static int fill_slot(struct cache_slot *slot) /* Generate cache content */ slot->fn(); + /* update stat info */ + if (fstat(slot->lock_fd, &slot->cache_st)) + return errno; + /* Restore stdout */ if (dup2(tmp, STDOUT_FILENO) == -1) return errno; @@ -319,7 +343,7 @@ int cache_process(int size, const char *path, const char *key, int ttl, int result; /* If the cache is disabled, just generate the content */ - if (size <= 0) { + if (size <= 0 || ttl == 0) { fn(); return 0; } @@ -184,6 +184,8 @@ static void config_cb(const char *name, const char *value) ctx.cfg.cache_dynamic_ttl = atoi(value); else if (!strcmp(name, "cache-about-ttl")) ctx.cfg.cache_about_ttl = atoi(value); + else if (!strcmp(name, "cache-snapshot-ttl")) + ctx.cfg.cache_snapshot_ttl = atoi(value); else if (!strcmp(name, "case-sensitive-sort")) ctx.cfg.case_sensitive_sort = atoi(value); else if (!strcmp(name, "about-filter")) @@ -331,6 +333,7 @@ static void prepare_context(void) ctx.cfg.cache_max_create_time = 5; ctx.cfg.cache_root = CGIT_CACHE_ROOT; ctx.cfg.cache_about_ttl = 15; + ctx.cfg.cache_snapshot_ttl = 5; ctx.cfg.cache_repo_ttl = 5; ctx.cfg.cache_root_ttl = 5; ctx.cfg.cache_scanrc_ttl = 15; @@ -921,6 +924,23 @@ static void cgit_parse_args(int argc, const char **argv) int scan = 0; for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "--version")) { + printf("CGit %s | http://git.zx2c4.com/cgit/\n\nCompiled in features:\n", CGIT_VERSION); +#ifdef NO_LUA + printf("[-] "); +#else + printf("[+] "); +#endif + printf("Lua scripting\n"); +#ifndef HAVE_LINUX_SENDFILE + printf("[-] "); +#else + printf("[+] "); +#endif + printf("Linux sendfile() usage\n"); + + exit(0); + } if (!prefixcmp(argv[i], "--cache=")) { ctx.cfg.cache_root = xstrdup(argv[i] + 8); } else if (!strcmp(argv[i], "--nocache")) { @@ -978,6 +998,9 @@ static int calc_ttl() if (!strcmp(ctx.qry.page, "about")) return ctx.cfg.cache_about_ttl; + if (!strcmp(ctx.qry.page, "snapshot")) + return ctx.cfg.cache_snapshot_ttl; + if (ctx.qry.has_sha1) return ctx.cfg.cache_static_ttl; @@ -210,6 +210,7 @@ struct cgit_config { int cache_scanrc_ttl; int cache_static_ttl; int cache_about_ttl; + int cache_snapshot_ttl; int case_sensitive_sort; int embedded; int enable_filter_overrides; @@ -29,30 +29,18 @@ ifdef NO_LUA LUA_MESSAGE := linking without specified Lua support CGIT_CFLAGS += -DNO_LUA else -LUAJIT_CFLAGS := $(shell pkg-config --cflags luajit 2>/dev/null) -LUAJIT_LIBS := $(shell pkg-config --libs luajit 2>/dev/null) -LUA_LIBS := $(shell pkg-config --libs lua 2>/dev/null) -LUA_CFLAGS := $(shell pkg-config --cflags lua 2>/dev/null) -ifeq (JIT,$(LUA_IMPLEMENTATION)) - ifeq ($(strip $(LUAJIT_LIBS)),) - $(error LuaJIT specified via LUA_IMPLEMENTATION=JIT, but library could not be found.) - endif - LUA_MESSAGE := linking with selected LuaJIT - CGIT_LIBS += $(LUAJIT_LIBS) - CGIT_CFLAGS += $(LUAJIT_CFLAGS) -else ifeq (VANILLA,$(LUA_IMPLEMENTATION)) - ifeq ($(strip $(LUA_LIBS)),) - $(error Lua specified via LUA_IMPLEMENTATION=VANILLA, but library could not be found.) - endif - LUA_MESSAGE := linking with selected Lua - CGIT_LIBS += $(LUA_LIBS) - CGIT_LIBS += $(LUA_CFLAGS) -else ifneq ($(strip $(LUAJIT_LIBS)),) - LUA_MESSAGE := linking with autodetected LuaJIT - CGIT_LIBS += $(LUAJIT_LIBS) - CGIT_CFLAGS += $(LUAJIT_CFLAGS) -else ifneq ($(strip $(LUA_LIBS)),) - LUA_MESSAGE := linking with autodetected Lua +ifeq ($(LUA_PKGCONFIG),) + LUA_PKGCONFIG := $(shell for pc in luajit lua lua5.2 lua5.1; do \ + pkg-config --exists $$pc 2>/dev/null && echo $$pc && break; \ + done) + LUA_MODE := autodetected +else + LUA_MODE := specified +endif +ifneq ($(LUA_PKGCONFIG),) + LUA_MESSAGE := linking with $(LUA_MODE) $(LUA_PKGCONFIG) + LUA_LIBS := $(shell pkg-config --libs $(LUA_PKGCONFIG) 2>/dev/null) + LUA_CFLAGS := $(shell pkg-config --cflags $(LUA_PKGCONFIG) 2>/dev/null) CGIT_LIBS += $(LUA_LIBS) CGIT_CFLAGS += $(LUA_CFLAGS) else @@ -68,6 +56,14 @@ ifeq ($(findstring BSD,$(uname_S)),) CGIT_LIBS += -ldl endif +# glibc 2.1+ offers sendfile which the most common C library on Linux +ifeq ($(uname_S),Linux) + HAVE_LINUX_SENDFILE = YesPlease +endif + +ifdef HAVE_LINUX_SENDFILE + CGIT_CFLAGS += -DHAVE_LINUX_SENDFILE +endif CGIT_OBJ_NAMES += cgit.o CGIT_OBJ_NAMES += cache.o diff --git a/cgitrc.5.txt b/cgitrc.5.txt index 8eafc4a..cbaebca 100644 --- a/cgitrc.5.txt +++ b/cgitrc.5.txt @@ -60,37 +60,41 @@ cache-root:: cache-static-ttl:: Number which specifies the time-to-live, in minutes, for the cached - version of repository pages accessed with a fixed SHA1. Negative - values have infinite ttl. Default value: -1". + version of repository pages accessed with a fixed SHA1. See also: + "CACHE". Default value: -1". cache-dynamic-ttl:: Number which specifies the time-to-live, in minutes, for the cached - version of repository pages accessed without a fixed SHA1. Negative - values have infinite ttl. Default value: "5". + version of repository pages accessed without a fixed SHA1. See also: + "CACHE". Default value: "5". cache-repo-ttl:: Number which specifies the time-to-live, in minutes, for the cached - version of the repository summary page. Negative values have infinite - ttl. Default value: "5". + version of the repository summary page. See also: "CACHE". Default + value: "5". cache-root-ttl:: Number which specifies the time-to-live, in minutes, for the cached - version of the repository index page. Negative values have infinite - ttl. Default value: "5". + version of the repository index page. See also: "CACHE". Default + value: "5". cache-scanrc-ttl:: Number which specifies the time-to-live, in minutes, for the result - of scanning a path for git repositories. Negative values have infinite - ttl. Default value: "15". + of scanning a path for git repositories. See also: "CACHE". Default + value: "15". cache-about-ttl:: Number which specifies the time-to-live, in minutes, for the cached - version of the repository about page. Negative values have infinite - ttl. Default value: "15". + version of the repository about page. See also: "CACHE". Default + value: "15". + +cache-snapshot-ttl:: + Number which specifies the time-to-live, in minutes, for the cached + version of snapshots. See also: "CACHE". Default value: "5". cache-size:: - The maximum number of entries in the cgit cache. Default value: "0" - (i.e. caching is disabled). + The maximum number of entries in the cgit cache. When set to "0", + caching is disabled. See also: "CACHE". Default value: "0" case-sensitive-sort:: Sort items in the repo list case sensitively. Default value: "1". @@ -712,6 +716,16 @@ the environment variables defined in "FILTER API": - repo.clone-url +CACHE +------ + +All cache ttl values are in minutes. Negative ttl values indicate that a page +type will never expire, and thus the first time a URL is accessed, the result +will be cached indefinitely, even if the underlying git repository changes. +Conversely, when a ttl value is zero, the cache is disabled for that +particular page type, and the page type is never cached. + + EXAMPLE CGITRC FILE ------------------- @@ -113,7 +113,7 @@ static void refs_fn(void) static void snapshot_fn(void) { cgit_print_snapshot(ctx.qry.head, ctx.qry.sha1, ctx.qry.path, - ctx.repo->snapshots, ctx.qry.nohead); + ctx.qry.nohead); } static void stats_fn(void) diff --git a/filters/simple-authentication.lua b/filters/simple-authentication.lua index 230d3a3..cc86b7e 100644 --- a/filters/simple-authentication.lua +++ b/filters/simple-authentication.lua @@ -166,7 +166,7 @@ function url_encode(str) return "" end str = string.gsub(str, "\n", "\r\n") - str = string.gsub(str, "([^%w ])", function (c) return string.format("%%%02X", string.byte(c)) end) + str = string.gsub(str, "([^%w ])", function(c) return string.format("%%%02X", string.byte(c)) end) str = string.gsub(str, " ", "+") return str end diff --git a/gen-version.sh b/gen-version.sh index 3a08015..80cf49a 100755 --- a/gen-version.sh +++ b/gen-version.sh @@ -4,7 +4,7 @@ V=$1 # Use `git describe` to get current version if we're inside a git repo -if test -d .git +if test "$(git rev-parse --git-dir 2>/dev/null)" = '.git' then V=$(git describe --abbrev=4 HEAD 2>/dev/null) fi diff --git a/git b/git -Subproject d2446dfd7f3b3f8948142cfb07a0270e2497d93 +Subproject 5f95c9f850b19b368c43ae399cc831b17a26a5a @@ -368,6 +368,7 @@ void cgit_diff_tree(const unsigned char *old_sha1, struct diff_options opt; struct pathspec_item item; + memset(&item, 0, sizeof(item)); diff_setup(&opt); opt.output_format = DIFF_FORMAT_CALLBACK; opt.detect_rename = 1; diff --git a/tests/setup.sh b/tests/setup.sh index 785edd7..7590f04 100755 --- a/tests/setup.sh +++ b/tests/setup.sh @@ -60,6 +60,12 @@ fi FILTER_DIRECTORY=$(cd ../filters && pwd) +if cgit --version | grep -F -q "[+] Lua scripting"; then + export CGIT_HAS_LUA=1 +else + export CGIT_HAS_LUA=0 +fi + mkrepo() { name=$1 count=$2 @@ -133,7 +139,10 @@ repo.commit-filter=exec:$FILTER_DIRECTORY/dump.sh repo.email-filter=exec:$FILTER_DIRECTORY/dump.sh repo.source-filter=exec:$FILTER_DIRECTORY/dump.sh repo.readme=master:a+b +EOF + if [ $CGIT_HAS_LUA -eq 1 ]; then + cat >>cgitrc <<EOF repo.url=filter-lua repo.path=$PWD/repos/filter/.git repo.desc=filtered repo @@ -143,6 +152,7 @@ repo.email-filter=lua:$FILTER_DIRECTORY/dump.lua repo.source-filter=lua:$FILTER_DIRECTORY/dump.lua repo.readme=master:a+b EOF + fi } cgit_query() @@ -155,7 +165,7 @@ cgit_url() CGIT_CONFIG="$PWD/cgitrc" QUERY_STRING="url=$1" cgit } -strip_headers () { +strip_headers() { while read -r line do test -z "$line" && break diff --git a/tests/t0111-filter.sh b/tests/t0111-filter.sh index 730f1c0..2fdc366 100755 --- a/tests/t0111-filter.sh +++ b/tests/t0111-filter.sh @@ -3,7 +3,12 @@ test_description='Check filtered content' . ./setup.sh -for prefix in exec lua +prefixes="exec" +if [ $CGIT_HAS_LUA -eq 1 ]; then + prefixes="$prefixes lua" +fi + +for prefix in $prefixes do test_expect_success "generate filter-$prefix/tree/a%2bb" " cgit_url 'filter-$prefix/tree/a%2bb' >tmp @@ -11,18 +11,10 @@ #include "html.h" #include "ui-shared.h" -static int cmp_age(int age1, int age2) +static inline int cmp_age(int age1, int age2) { - if (age1 != 0 && age2 != 0) - return age2 - age1; - - if (age1 == 0 && age2 == 0) - return 0; - - if (age1 == 0) - return +1; - - return -1; + /* age1 and age2 are assumed to be non-negative */ + return age2 - age1; } static int cmp_ref_name(const void *a, const void *b) @@ -105,7 +97,7 @@ static void print_tag_downloads(const struct cgit_repo *repo, const char *ref) const char *basename; int free_ref = 0; - if (!ref || strlen(ref) < 2) + if (!ref || strlen(ref) < 1) return; basename = cgit_repobasename(repo->url); diff --git a/ui-snapshot.c b/ui-snapshot.c index 582dc31..3107b05 100644 --- a/ui-snapshot.c +++ b/ui-snapshot.c @@ -193,7 +193,7 @@ static void show_error(char *fmt, ...) } void cgit_print_snapshot(const char *head, const char *hex, - const char *filename, int snapshots, int dwim) + const char *filename, int dwim) { const struct cgit_snapshot_format* f; char *prefix = NULL; diff --git a/ui-snapshot.h b/ui-snapshot.h index b6ede52..a8deec3 100644 --- a/ui-snapshot.h +++ b/ui-snapshot.h @@ -2,6 +2,6 @@ #define UI_SNAPSHOT_H extern void cgit_print_snapshot(const char *head, const char *hex, - const char *filename, int snapshot, int dwim); + const char *filename, int dwim); #endif /* UI_SNAPSHOT_H */ |