]>
git.cameronkatri.com Git - cgit.git/blob - cache.c
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)
12 const int NOLOCK
= -1;
14 char *cache_safe_filename(const char *unsafe
)
16 static char buf
[4][PATH_MAX
];
25 while(unsafe
&& (c
= *unsafe
++) != 0) {
26 if (c
== '/' || c
== ' ' || c
== '&' || c
== '|' ||
27 c
== '>' || c
== '<' || c
== '.')
35 int cache_exist(struct cacheitem
*item
)
37 if (stat(item
->name
, &item
->st
)) {
38 item
->st
.st_mtime
= 0;
44 int cache_create_dirs()
48 path
= fmt("%s", ctx
.cfg
.cache_root
);
49 if (mkdir(path
, S_IRWXU
) && errno
!=EEXIST
)
55 path
= fmt("%s/%s", ctx
.cfg
.cache_root
,
56 cache_safe_filename(ctx
.repo
->url
));
58 if (mkdir(path
, S_IRWXU
) && errno
!=EEXIST
)
62 path
= fmt("%s/%s/%s", ctx
.cfg
.cache_root
,
63 cache_safe_filename(ctx
.repo
->url
),
65 if (mkdir(path
, S_IRWXU
) && errno
!=EEXIST
)
71 int cache_refill_overdue(const char *lockfile
)
75 if (stat(lockfile
, &st
))
78 return (time(NULL
) - st
.st_mtime
> ctx
.cfg
.cache_max_create_time
);
81 int cache_lock(struct cacheitem
*item
)
84 char *lockfile
= xstrdup(fmt("%s.lock", item
->name
));
87 if (++i
> ctx
.cfg
.max_lock_attempts
)
88 die("cache_lock: unable to lock %s: %s",
89 item
->name
, strerror(errno
));
91 item
->fd
= open(lockfile
, O_WRONLY
|O_CREAT
|O_EXCL
, S_IRUSR
|S_IWUSR
);
93 if (item
->fd
== NOLOCK
&& errno
== ENOENT
&& cache_create_dirs())
96 if (item
->fd
== NOLOCK
&& errno
== EEXIST
&&
97 cache_refill_overdue(lockfile
) && !unlink(lockfile
))
101 return (item
->fd
> 0);
104 int cache_unlock(struct cacheitem
*item
)
107 return (rename(fmt("%s.lock", item
->name
), item
->name
) == 0);
110 int cache_cancel_lock(struct cacheitem
*item
)
112 return (unlink(fmt("%s.lock", item
->name
)) == 0);
115 int cache_expired(struct cacheitem
*item
)
119 return item
->st
.st_mtime
+ item
->ttl
* 60 < time(NULL
);