diff --git a/doc/fccache.fncs b/doc/fccache.fncs index f35c5d7..2f5fa47 100644 --- a/doc/fccache.fncs +++ b/doc/fccache.fncs @@ -66,3 +66,12 @@ This returns the total number of subdirectories in the cache. This returns the number of fonts which would be included in the return from FcCacheCopySet. @@ + +@RET@ FcBool +@FUNC@ FcDirCacheClean +@TYPE1@ const FcChar8 * @ARG1@ cache_dir +@TYPE2@ FcBool @ARG2@ verbose +@PURPOSE@ +This tries to clean up the cache directory of cache_dir. +This returns FcTrue if the operation is successfully complete. otherwise FcFalse. +@@ diff --git a/fc-cache/fc-cache.c b/fc-cache/fc-cache.c index 24bb2ec..b42fd35 100644 --- a/fc-cache/fc-cache.c +++ b/fc-cache/fc-cache.c @@ -32,7 +32,6 @@ #endif #include -#include "../src/fcarch.h" #include #include #include @@ -318,96 +317,6 @@ scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, return ret; } -static FcBool -cleanCacheDirectory (FcConfig *config, FcChar8 *dir, FcBool verbose) -{ - DIR *d; - struct dirent *ent; - FcChar8 *dir_base; - FcBool ret = FcTrue; - FcBool remove; - FcCache *cache; - struct stat target_stat; - - dir_base = FcStrPlus (dir, (FcChar8 *) "/"); - if (!dir_base) - { - fprintf (stderr, "%s: out of memory\n", dir); - return FcFalse; - } - if (access ((char *) dir, W_OK) != 0) - { - if (verbose) - printf ("%s: not cleaning %s cache directory\n", dir, - access ((char *) dir, F_OK) == 0 ? "unwritable" : "non-existent"); - FcStrFree (dir_base); - return FcTrue; - } - if (verbose) - printf ("%s: cleaning cache directory\n", dir); - d = opendir ((char *) dir); - if (!d) - { - perror ((char *) dir); - FcStrFree (dir_base); - return FcFalse; - } - while ((ent = readdir (d))) - { - FcChar8 *file_name; - const FcChar8 *target_dir; - - if (ent->d_name[0] == '.') - continue; - /* skip cache files for different architectures and */ - /* files which are not cache files at all */ - if (strlen(ent->d_name) != 32 + strlen ("-" FC_ARCHITECTURE FC_CACHE_SUFFIX) || - strcmp(ent->d_name + 32, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX)) - continue; - - file_name = FcStrPlus (dir_base, (FcChar8 *) ent->d_name); - if (!file_name) - { - fprintf (stderr, "%s: allocation failure\n", dir); - ret = FcFalse; - break; - } - remove = FcFalse; - cache = FcDirCacheLoadFile (file_name, NULL); - if (!cache) - { - if (verbose) - printf ("%s: invalid cache file: %s\n", dir, ent->d_name); - remove = FcTrue; - } - else - { - target_dir = FcCacheDir (cache); - if (stat ((char *) target_dir, &target_stat) < 0) - { - if (verbose) - printf ("%s: %s: missing directory: %s \n", - dir, ent->d_name, target_dir); - remove = FcTrue; - } - } - if (remove) - { - if (unlink ((char *) file_name) < 0) - { - perror ((char *) file_name); - ret = FcFalse; - } - } - FcDirCacheUnload (cache); - FcStrFree (file_name); - } - - closedir (d); - FcStrFree (dir_base); - return ret; -} - static FcBool cleanCacheDirectories (FcConfig *config, FcBool verbose) { @@ -419,7 +328,7 @@ cleanCacheDirectories (FcConfig *config, FcBool verbose) return FcFalse; while ((cache_dir = FcStrListNext (cache_dirs))) { - if (!cleanCacheDirectory (config, cache_dir, verbose)) + if (!FcDirCacheClean (cache_dir, verbose)) { ret = FcFalse; break; diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index 8936d83..0e2ca50 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -328,6 +328,9 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config); FcPublic FcBool FcDirCacheValid (const FcChar8 *cache_file); +FcPublic FcBool +FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose); + /* fccfg.c */ FcPublic FcChar8 * FcConfigHome (void); diff --git a/src/fccache.c b/src/fccache.c index 343ece9..b7ba1fd 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -1020,6 +1020,97 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) return FcFalse; } +FcBool +FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) +{ + DIR *d; + struct dirent *ent; + FcChar8 *dir_base; + FcBool ret = FcTrue; + FcBool remove; + FcCache *cache; + struct stat target_stat; + + dir_base = FcStrPlus (cache_dir, (FcChar8 *) FC_DIR_SEPARATOR_S); + if (!dir_base) + { + fprintf (stderr, "Fontconfig error: %s: out of memory\n", cache_dir); + return FcFalse; + } + if (access ((char *) cache_dir, W_OK) != 0) + { + if (verbose || FcDebug () & FC_DBG_CACHE) + printf ("%s: not cleaning %s cache directory\n", cache_dir, + access ((char *) cache_dir, F_OK) == 0 ? "unwritable" : "non-existent"); + goto bail0; + } + if (verbose || FcDebug () & FC_DBG_CACHE) + printf ("%s: cleaning cache directory\n", cache_dir); + d = opendir ((char *) cache_dir); + if (!d) + { + perror ((char *) cache_dir); + ret = FcFalse; + goto bail0; + } + while ((ent = readdir (d))) + { + FcChar8 *file_name; + const FcChar8 *target_dir; + + if (ent->d_name[0] == '.') + continue; + /* skip cache files for different architectures and */ + /* files which are not cache files at all */ + if (strlen(ent->d_name) != 32 + strlen ("-" FC_ARCHITECTURE FC_CACHE_SUFFIX) || + strcmp(ent->d_name + 32, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX)) + continue; + + file_name = FcStrPlus (dir_base, (FcChar8 *) ent->d_name); + if (!file_name) + { + fprintf (stderr, "Fontconfig error: %s: allocation failure\n", cache_dir); + ret = FcFalse; + break; + } + remove = FcFalse; + cache = FcDirCacheLoadFile (file_name, NULL); + if (!cache) + { + if (verbose || FcDebug () & FC_DBG_CACHE) + printf ("%s: invalid cache file: %s\n", cache_dir, ent->d_name); + remove = FcTrue; + } + else + { + target_dir = FcCacheDir (cache); + if (stat ((char *) target_dir, &target_stat) < 0) + { + if (verbose || FcDebug () & FC_DBG_CACHE) + printf ("%s: %s: missing directory: %s \n", + cache_dir, ent->d_name, target_dir); + remove = FcTrue; + } + } + if (remove) + { + if (unlink ((char *) file_name) < 0) + { + perror ((char *) file_name); + ret = FcFalse; + } + } + FcDirCacheUnload (cache); + FcStrFree (file_name); + } + + closedir (d); + bail0: + FcStrFree (dir_base); + + return ret; +} + /* * Hokey little macro trick to permit the definitions of C functions * with the same name as CPP macros diff --git a/src/fcint.h b/src/fcint.h index 0dfc236..ba4b388 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -64,8 +64,10 @@ typedef HRESULT (WINAPI *pfnSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR); extern pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory; extern pfnSHGetFolderPathA pSHGetFolderPathA; # define FC_SEARCH_PATH_SEPARATOR ';' +# define FC_DIR_SEPARATOR_S "\\" #else # define FC_SEARCH_PATH_SEPARATOR ':' +# define FC_DIR_SEPARATOR_S "/" #endif #define FC_DBG_MATCH 1