Commit d8ab9e6c authored by Keith Packard's avatar Keith Packard
Browse files

Automatically remove invalid cache files.

Cache files for missing or more recently modified directories are
automatically removed at the end of every fc-cache run.
parent e9a564e2
......@@ -35,7 +35,7 @@ install-data-local:
uninstall-local:
-$(RM) -rf "$(DESTDIR)$(pkgcachedir)"
INCLUDES=-I${top_srcdir} $(FREETYPE_CFLAGS)
INCLUDES=-I${top_srcdir} -I${top_srcdir}/src $(FREETYPE_CFLAGS)
bin_PROGRAMS=fc-cache
......
......@@ -31,13 +31,15 @@
#define HAVE_GETOPT 1
#endif
#include <fontconfig/fontconfig.h>
#include "fcint.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#if defined (_WIN32)
#define STRICT
......@@ -46,6 +48,10 @@
#undef STRICT
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifndef HAVE_GETOPT
#define HAVE_GETOPT 0
#endif
......@@ -266,6 +272,126 @@ scanDirs (FcStrList *list, FcConfig *config, char *program, FcBool force, FcBool
return ret;
}
FcCache *
FcCacheFileMap (const FcChar8 *file, struct stat *file_stat)
{
FcCache *cache;
int fd;
fd = open (file, O_RDONLY | O_BINARY);
if (fd < 0)
return NULL;
if (fstat (fd, file_stat) < 0) {
close (fd);
return NULL;
}
if (FcDirCacheLoad (fd, file_stat->st_size, &cache)) {
close (fd);
return cache;
}
close (fd);
return NULL;
}
static FcBool
cleanCacheDirectory (FcConfig *config, FcChar8 *dir, FcBool verbose)
{
DIR *d;
struct dirent *ent;
char *dir_base;
FcBool ret = FcTrue;
FcBool remove;
FcCache *cache;
struct stat file_stat;
struct stat target_stat;
dir_base = FcStrPlus (dir, "/");
if (access ((char *) dir, W_OK|X_OK) != 0)
{
if (verbose)
printf ("%s: skipping unwritable cache directory\n", dir);
return FcTrue;
}
d = opendir (dir);
if (!d)
{
perror (dir);
return FcFalse;
}
while ((ent = readdir (d)))
{
FcChar8 *file_name;
FcChar8 *target_dir;
if (ent->d_name[0] == '.')
continue;
file_name = FcStrPlus (dir_base, ent->d_name);
if (!file_name)
{
fprintf (stderr, "%s: allocation failure\n", dir);
ret = FcFalse;
break;
}
cache = FcCacheFileMap (file_name, &file_stat);
if (!cache)
{
fprintf (stderr, "%s: invalid cache file: %s\n", dir, ent->d_name);
FcStrFree (file_name);
ret = FcFalse;
continue;
}
target_dir = FcCacheDir (cache);
remove = FcFalse;
if (stat (target_dir, &target_stat) < 0)
{
if (verbose)
printf ("%s: %s: missing directory: %s \n",
dir, ent->d_name, target_dir);
remove = FcTrue;
}
else if (target_stat.st_mtime > file_stat.st_mtime)
{
if (verbose)
printf ("%s: %s: cache outdated: %s\n",
dir, ent->d_name, target_dir);
remove = FcTrue;
}
if (remove)
{
if (unlink (file_name) < 0)
{
perror (file_name);
ret = FcFalse;
}
}
FcStrFree (file_name);
}
closedir (d);
return ret;
}
static FcBool
cleanCacheDirectories (FcConfig *config, FcBool verbose)
{
FcStrList *cache_dirs = FcConfigGetCacheDirs (config);
FcChar8 *cache_dir;
FcBool ret = FcTrue;
if (!cache_dirs)
return FcFalse;
while ((cache_dir = FcStrListNext (cache_dirs)))
{
if (!cleanCacheDirectory (config, cache_dir, verbose))
{
ret = FcFalse;
break;
}
}
FcStrListDone (cache_dirs);
return ret;
}
int
main (int argc, char **argv)
{
......@@ -356,6 +482,8 @@ main (int argc, char **argv)
FcStrSetDestroy (processed_dirs);
cleanCacheDirectories (config, verbose);
/*
* Now we need to sleep a second (or two, to be extra sure), to make
* sure that timestamps for changes after this run of fc-cache are later
......
......@@ -31,8 +31,7 @@
#define HAVE_GETOPT 1
#endif
#include <fontconfig/fontconfig.h>
#include <../src/fccache.c>
#include "../src/fccache.c"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
......
......@@ -241,8 +241,8 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
return ret;
}
static FcBool
FcCacheLoad (int fd, off_t size, void *closure)
FcBool
FcDirCacheLoad (int fd, off_t size, void *closure)
{
FcCache *cache;
FcBool allocated = FcFalse;
......@@ -308,7 +308,7 @@ FcDirCacheMap (const FcChar8 *dir, FcConfig *config)
FcCache *cache = NULL;
if (!FcDirCacheProcess (config, dir,
FcCacheLoad,
FcDirCacheLoad,
&cache))
return NULL;
return cache;
......
......@@ -511,7 +511,7 @@ FcDirCacheMap (const FcChar8 *dir, FcConfig *config);
FcBool
FcDirCacheLoad (int fd, off_t size, void *closure);
/* fccfg.c */
FcBool
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment