43 #ifdef HAVE_SYS_STAT_H
46 #ifdef HAVE_SYS_TYPES_H
47 #include <sys/types.h>
66 #define ISDOT(x) ( (x)[0] == '.' && (!(x)[1] || ((x)[1] == '.' && !(x)[2])) )
68 #define BLANKSTR(x) ( !(x) ? "#" : (x) )
70 #define ISBLANK(x) ( ((x)[0] == '#') && ((x)[1] == '\0') )
90 mi_rerror(
"(%s) Can't create/delete directory.", caller);
105 mi_rerror(
"(%s) Permission denied.", caller);
111 mi_rerror(
"(%s) Too many open files!", caller);
115 mi_rerror(
"(%s) Pathname was too long.", caller);
128 mi_rerror(
"(%s) Out Of Memory!", caller);
132 mi_rerror(
"(%s) Read-Only filesystem!", caller);
136 mi_rerror(
"(%s) Too many symbolic links.", caller);
145 mi_rerror(
"(%s) No space left on device!", caller);
148 mi_rerror(
"(%s) - error_handler! %s", caller, strerror(errno));
169 register unsigned short l = 0, m = 0;
170 char *tempdir = NULL;
174 tempdir = realloc(tempdir, (m + (l = strcspn(dirpath + m,
"/")) + 1));
179 strncpy(tempdir, dirpath, m + l);
187 while (dirpath[m] ==
'/')
190 if (mkdir(tempdir, S_IRWXU)) {
219 struct dirent *cachedirent = NULL;
220 struct stat origdirstat;
221 const char *origdir = NULL;
223 if (
unlikely(fchdir(dirfd(cachedir))))
226 while ((cachedirent = readdir(cachedir))) {
227 if (
ISDOT(cachedirent->d_name))
230 if (unlink(cachedirent->d_name)) {
231 if ((errno == EISDIR) || (errno == EPERM)) {
237 origdir =
apr_pstrcat(r->pool, curdir,
"/", cachedirent->d_name, NULL);
238 if (stat(origdir, &origdirstat)) {
239 if (rmdir(cachedirent->d_name)) {
240 if (errno == ENOTEMPTY) {
241 subdir = opendir(cachedirent->d_name);
244 if (fchdir(dirfd(cachedir)));
245 rmdir(cachedirent->d_name);
281 const char *
const filename,
const char * uri,
unsigned long soptions)
284 DIR *cachedir = NULL;
285 struct stat cachedirstat, dirstat;
296 if (!(cachedir = opendir(filename + 1))) {
297 if (errno == ENOENT) {
305 fstat(dirfd(cachedir), &cachedirstat);
306 stat(filename, &dirstat);
307 if (cachedirstat.st_mtime < dirstat.st_mtime)
346 const char *
const filename)
351 unsigned short track, posn, flags, cvers = 0;
354 FILE *cache_file = NULL;
364 fdesc = open(filename + 1, O_RDONLY|O_NONBLOCK);
366 if (
likely((errno == ENOENT) || (errno == EWOULDBLOCK) || (errno == EAGAIN)))
375 if (flock(fdesc, LOCK_SH|LOCK_NB)) {
380 cache_file = fdopen(fdesc,
"r");
391 if (
likely(data_buffer)) {
392 result = fscanf(cache_file,
"album: %[^\n]\nartist: %[^\n]\n"
393 "title: %[^\n]\ndate: %hu\ntrack: %hu\nposn: %hu\n"
394 "length: %hu\nbitrate: %lu\nfreq: %hu\nsize: %lu\n"
395 "filetype: %hi\ngenre: %[^\n]\nmtime: %lu\nflags: %hx\n"
455 FILE *cache_file = NULL;
465 fdesc = open(filename + 1, O_WRONLY|O_NONBLOCK|O_CREAT, S_IRUSR|S_IWUSR);
467 if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
475 if (flock(fdesc, LOCK_EX|LOCK_NB)) {
480 cache_file = fdopen(fdesc,
"w");
486 fprintf(cache_file,
"album: %s\nartist: %s\ntitle: %s\ndate: %hu\n"
487 "track: %hhu\nposn: %hhu\nlength: %hu\nbitrate: %lu\nfreq: %hu\n"
488 "size: %lu\nfiletype: %hi\ngenre: %s\nmtime: %lu\nflags: %hhx\ncvers: %hu\n",
515 server_rec *s = cmd->server;
516 static const char biniou[] =
"file://";
519 if (strncmp(biniou, setup_string, 7) == 0) {
521 char *restrict csetup =
apr_pstrdup(cmd->pool, setup_string+6);
525 if (csetup[0] !=
'/') {
527 mi_serror(
"Non absolute cache directory path: %s", csetup);
531 if ( (access(csetup, X_OK|W_OK)) || (chdir((
char *)(csetup))) ) {
542 mi_serror(
"Error setting up %s cache!",
"file");