1 /* cache.c: cache management
3 * Copyright (C) 2006 Lars Hjemli
5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text)
11 const int NOLOCK
= -1;
13 char *cache_safe_filename(const char *unsafe
)
15 static char buf
[PATH_MAX
];
19 while(unsafe
&& (c
= *unsafe
++) != 0) {
20 if (c
== '/' || c
== ' ' || c
== '&' || c
== '|' ||
21 c
== '>' || c
== '<' || c
== '.')
29 int cache_exist(struct cacheitem
*item
)
31 if (stat(item
->name
, &item
->st
)) {
32 item
->st
.st_mtime
= 0;
38 int cache_create_dirs()
42 path
= fmt("%s", cgit_cache_root
);
43 if (mkdir(path
, S_IRWXU
) && errno
!=EEXIST
)
49 path
= fmt("%s/%s", cgit_cache_root
, cgit_query_repo
);
50 if (mkdir(path
, S_IRWXU
) && errno
!=EEXIST
)
53 if (cgit_query_page
) {
54 path
= fmt("%s/%s/%s", cgit_cache_root
, cgit_query_repo
,
56 if (mkdir(path
, S_IRWXU
) && errno
!=EEXIST
)
62 int cache_refill_overdue(const char *lockfile
)
66 if (stat(lockfile
, &st
))
69 return (time(NULL
) - st
.st_mtime
> cgit_cache_max_create_time
);
72 int cache_lock(struct cacheitem
*item
)
75 char *lockfile
= xstrdup(fmt("%s.lock", item
->name
));
78 if (++i
> cgit_max_lock_attempts
)
79 die("cache_lock: unable to lock %s: %s",
80 item
->name
, strerror(errno
));
82 item
->fd
= open(lockfile
, O_WRONLY
|O_CREAT
|O_EXCL
, S_IRUSR
|S_IWUSR
);
84 if (item
->fd
== NOLOCK
&& errno
== ENOENT
&& cache_create_dirs())
87 if (item
->fd
== NOLOCK
&& errno
== EEXIST
&&
88 cache_refill_overdue(lockfile
) && !unlink(lockfile
))
92 return (item
->fd
> 0);
95 int cache_unlock(struct cacheitem
*item
)
98 return (rename(fmt("%s.lock", item
->name
), item
->name
) == 0);
101 int cache_cancel_lock(struct cacheitem
*item
)
103 return (unlink(fmt("%s.lock", item
->name
)) == 0);
106 int cache_expired(struct cacheitem
*item
)
110 return item
->st
.st_mtime
+ item
->ttl
* 60 < time(NULL
);