summaryrefslogtreecommitdiffabout
path: root/cache.c
Unidiff
Diffstat (limited to 'cache.c') (more/less context) (ignore whitespace changes)
-rw-r--r--cache.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/cache.c b/cache.c
index 1be1ea4..b034c48 100644
--- a/cache.c
+++ b/cache.c
@@ -1,86 +1,94 @@
1/* cache.c: cache management
2 *
3 * Copyright (C) 2006 Lars Hjemli
4 *
5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text)
7 */
8
1#include "cgit.h" 9#include "cgit.h"
2 10
3const int NOLOCK = -1; 11const int NOLOCK = -1;
4 12
5int cache_lookup(struct cacheitem *item) 13int cache_lookup(struct cacheitem *item)
6{ 14{
7 if (!cgit_query_repo) { 15 if (!cgit_query_repo) {
8 item->name = xstrdup(fmt("%s/index.html", cgit_cache_root)); 16 item->name = xstrdup(fmt("%s/index.html", cgit_cache_root));
9 item->ttl = cgit_cache_root_ttl; 17 item->ttl = cgit_cache_root_ttl;
10 } else if (!cgit_query_page) { 18 } else if (!cgit_query_page) {
11 item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root, 19 item->name = xstrdup(fmt("%s/%s/index.html", cgit_cache_root,
12 cgit_query_repo)); 20 cgit_query_repo));
13 item->ttl = cgit_cache_repo_ttl; 21 item->ttl = cgit_cache_repo_ttl;
14 } else { 22 } else {
15 item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root, 23 item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root,
16 cgit_query_repo, cgit_query_page, 24 cgit_query_repo, cgit_query_page,
17 cgit_querystring)); 25 cgit_querystring));
18 if (cgit_query_has_symref) 26 if (cgit_query_has_symref)
19 item->ttl = cgit_cache_dynamic_ttl; 27 item->ttl = cgit_cache_dynamic_ttl;
20 else if (cgit_query_has_sha1) 28 else if (cgit_query_has_sha1)
21 item->ttl = cgit_cache_static_ttl; 29 item->ttl = cgit_cache_static_ttl;
22 else 30 else
23 item->ttl = cgit_cache_repo_ttl; 31 item->ttl = cgit_cache_repo_ttl;
24 } 32 }
25 if (stat(item->name, &item->st)) { 33 if (stat(item->name, &item->st)) {
26 item->st.st_mtime = 0; 34 item->st.st_mtime = 0;
27 return 0; 35 return 0;
28 } 36 }
29 return 1; 37 return 1;
30} 38}
31 39
32int cache_create_dirs() 40int cache_create_dirs()
33{ 41{
34 char *path; 42 char *path;
35 43
36 if (!cgit_query_repo) 44 if (!cgit_query_repo)
37 return 0; 45 return 0;
38 46
39 path = fmt("%s/%s", cgit_cache_root, cgit_query_repo); 47 path = fmt("%s/%s", cgit_cache_root, cgit_query_repo);
40 if (mkdir(path, S_IRWXU) && errno!=EEXIST) 48 if (mkdir(path, S_IRWXU) && errno!=EEXIST)
41 return 0; 49 return 0;
42 50
43 if (cgit_query_page) { 51 if (cgit_query_page) {
44 path = fmt("%s/%s/%s", cgit_cache_root, cgit_query_repo, 52 path = fmt("%s/%s/%s", cgit_cache_root, cgit_query_repo,
45 cgit_query_page); 53 cgit_query_page);
46 if (mkdir(path, S_IRWXU) && errno!=EEXIST) 54 if (mkdir(path, S_IRWXU) && errno!=EEXIST)
47 return 0; 55 return 0;
48 } 56 }
49 return 1; 57 return 1;
50} 58}
51 59
52int cache_lock(struct cacheitem *item) 60int cache_lock(struct cacheitem *item)
53{ 61{
54 int ret; 62 int ret;
55 char *lockfile = fmt("%s.lock", item->name); 63 char *lockfile = fmt("%s.lock", item->name);
56 64
57 top: 65 top:
58 item->fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR); 66 item->fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR);
59 if (item->fd == NOLOCK && errno == ENOENT && cache_create_dirs()) 67 if (item->fd == NOLOCK && errno == ENOENT && cache_create_dirs())
60 goto top; 68 goto top;
61 if (item->fd == NOLOCK && errno == EEXIST) { 69 if (item->fd == NOLOCK && errno == EEXIST) {
62 struct stat st; 70 struct stat st;
63 time_t t; 71 time_t t;
64 if (stat(lockfile, &st)) 72 if (stat(lockfile, &st))
65 return ret; 73 return ret;
66 t = time(NULL); 74 t = time(NULL);
67 if (t-st.st_mtime > cgit_cache_max_create_time && 75 if (t-st.st_mtime > cgit_cache_max_create_time &&
68 !unlink(lockfile)) 76 !unlink(lockfile))
69 goto top; 77 goto top;
70 return 0; 78 return 0;
71 } 79 }
72 return (item->fd > 0); 80 return (item->fd > 0);
73} 81}
74 82
75int cache_unlock(struct cacheitem *item) 83int cache_unlock(struct cacheitem *item)
76{ 84{
77 close(item->fd); 85 close(item->fd);
78 return (rename(fmt("%s.lock", item->name), item->name) == 0); 86 return (rename(fmt("%s.lock", item->name), item->name) == 0);
79} 87}
80 88
81int cache_expired(struct cacheitem *item) 89int cache_expired(struct cacheitem *item)
82{ 90{
83 if (item->ttl < 0) 91 if (item->ttl < 0)
84 return 0; 92 return 0;
85 return item->st.st_mtime + item->ttl * 60 < time(NULL); 93 return item->st.st_mtime + item->ttl * 60 < time(NULL);
86} 94}