/* * Look for a cache file for the specified dir. Attempt * to use each one we find, stopping when the callback * indicates success */ static FcBool FcDirCacheProcess (FcConfig *config, const FcChar8 *dir, FcBool (*callback) (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure), void *closure, FcChar8 **cache_file_ret) { int fd = -1; FcChar8 cache_base[CACHEBASE_LEN]; FcStrList *list; FcChar8 *cache_dir, *d; struct stat file_stat, dir_stat; FcBool ret = FcFalse; const FcChar8 *sysroot = FcConfigGetSysRoot (config); if (sysroot) d = FcStrBuildFilename (sysroot, dir, NULL); else d = FcStrdup (dir); if (FcStatChecksum (d, &dir_stat) < 0) { FcStrFree (d); return FcFalse; } FcStrFree (d); FcDirCacheBasename (dir, cache_base); list = FcStrListCreate (config->cacheDirs); if (!list) return FcFalse; while ((cache_dir = FcStrListNext (list))) { FcChar8 *cache_hashed; if (sysroot) cache_hashed = FcStrBuildFilename (sysroot, cache_dir, cache_base, NULL); else cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL); if (!cache_hashed) break; fd = FcDirCacheOpenFile (cache_hashed, &file_stat); if (fd >= 0) { ret = (*callback) (config, fd, &file_stat, &dir_stat, closure); close (fd); if (ret) { if (cache_file_ret) *cache_file_ret = cache_hashed; else FcStrFree (cache_hashed); break; } } FcStrFree (cache_hashed); } FcStrListDone (list); return ret; }
static FcBool FcCacheTimeValid (FcConfig *config, FcCache *cache, struct stat *dir_stat) { struct stat dir_static; if (!dir_stat) { const FcChar8 *sysroot = FcConfigGetSysRoot (config); FcChar8 *d; if (sysroot) d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL); else d = FcStrdup (FcCacheDir (cache)); if (FcStatChecksum (d, &dir_static) < 0) { FcStrFree (d); return FcFalse; } FcStrFree (d); dir_stat = &dir_static; } if (FcDebug () & FC_DBG_CACHE) printf ("FcCacheTimeValid dir \"%s\" cache checksum %d dir checksum %d\n", FcCacheDir (cache), cache->checksum, (int) dir_stat->st_mtime); return cache->checksum == (int) dir_stat->st_mtime; }
static FcBool FcCacheTimeValid (FcCache *cache, struct stat *dir_stat) { struct stat dir_static; if (!dir_stat) { if (FcStatChecksum (FcCacheDir (cache), &dir_static) < 0) return FcFalse; dir_stat = &dir_static; } if (FcDebug () & FC_DBG_CACHE) printf ("FcCacheTimeValid dir \"%s\" cache checksum %d dir checksum %d\n", FcCacheDir (cache), cache->checksum, (int) dir_stat->st_mtime); return cache->checksum == (int) dir_stat->st_mtime; }
static FcBool FcCacheTimeValid (FcConfig *config, FcCache *cache, struct stat *dir_stat) { struct stat dir_static; FcBool fnano = FcTrue; if (!dir_stat) { const FcChar8 *sysroot = FcConfigGetSysRoot (config); FcChar8 *d; if (sysroot) d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL); else d = FcStrdup (FcCacheDir (cache)); if (FcStatChecksum (d, &dir_static) < 0) { FcStrFree (d); return FcFalse; } FcStrFree (d); dir_stat = &dir_static; } #ifdef HAVE_STRUCT_STAT_ST_MTIM fnano = (cache->checksum_nano == dir_stat->st_mtim.tv_nsec); if (FcDebug () & FC_DBG_CACHE) printf ("FcCacheTimeValid dir \"%s\" cache checksum %d.%ld dir checksum %d.%ld\n", FcCacheDir (cache), cache->checksum, (long)cache->checksum_nano, (int) dir_stat->st_mtime, dir_stat->st_mtim.tv_nsec); #else if (FcDebug () & FC_DBG_CACHE) printf ("FcCacheTimeValid dir \"%s\" cache checksum %d dir checksum %d\n", FcCacheDir (cache), cache->checksum, (int) dir_stat->st_mtime); #endif return cache->checksum == (int) dir_stat->st_mtime && fnano; }
/* * Scan the specified directory and construct a cache of its contents */ FcCache * FcDirCacheScan (const FcChar8 *dir, FcConfig *config) { FcStrSet *dirs; FcBool ret = FcTrue; FcFontSet *set; FcCache *cache = NULL; struct stat dir_stat; if (FcDebug () & FC_DBG_FONTSET) printf ("cache scan dir %s\n", dir); if (FcStatChecksum ((char *) dir, &dir_stat) < 0) { if (errno != ENOENT) ret = FcFalse; goto bail; } set = FcFontSetCreate(); if (!set) { ret = FcFalse; goto bail; } dirs = FcStrSetCreate (); if (!dirs) { ret = FcFalse; goto bail1; } /* * Scan the dir */ if (!FcDirScanConfig (set, dirs, NULL, dir, FcTrue, config)) { ret = FcFalse; goto bail2; } /* * Build the cache object */ cache = FcDirCacheBuild (set, dir, &dir_stat, dirs); if (!cache) { ret = FcFalse; goto bail2; } /* * Write out the cache file, ignoring any troubles */ FcDirCacheWrite (cache, config); bail2: FcStrSetDestroy (dirs); bail1: FcFontSetDestroy (set); bail: return cache; }