- return ret;
-}
-
-FcFontSet *
-FcCacheRead (FcConfig *config, FcGlobalCache * cache)
-{
- FcFontSet * s = FcFontSetCreate();
- if (!s)
- return 0;
-
- if (FcCacheReadDirs (config, cache, FcConfigGetConfigDirs (config), s))
- goto bail;
-
- return s;
-
- bail:
- FcFontSetDestroy (s);
- return 0;
-}
-
-static const char bin2hex[] = { '0', '1', '2', '3',
- '4', '5', '6', '7',
- '8', '9', 'a', 'b',
- 'c', 'd', 'e', 'f' };
-
-static char *
-FcDirCacheHashName (char * cache_file, int collisions)
-{
- unsigned char hash[16], hex_hash[33];
- char *cache_hashed;
- unsigned char uscore = '_';
- int cnt, i;
- FcChar8 *tmp;
- struct MD5Context ctx;
-
- MD5Init (&ctx);
- MD5Update (&ctx, (unsigned char *)cache_file, strlen (cache_file));
-
- for (i = 0; i < collisions; i++)
- MD5Update (&ctx, &uscore, 1);
-
- MD5Final (hash, &ctx);
-
- for (cnt = 0; cnt < 16; ++cnt)
- {
- hex_hash[2*cnt] = bin2hex[hash[cnt] >> 4];
- hex_hash[2*cnt+1] = bin2hex[hash[cnt] & 0xf];
- }
- hex_hash[32] = 0;
-
- tmp = FcStrPlus ((FcChar8 *)hex_hash, (FcChar8 *)FC_CACHE_SUFFIX);
- if (!tmp)
- return 0;
-
- cache_hashed = (char *)FcStrPlus ((FcChar8 *)PKGCACHEDIR"/", tmp);
- free (tmp);
-
- return cache_hashed;
-}
-
-/* Opens the hashed name for cache_file.
- * This would fail in the unlikely event of a collision and subsequent
- * removal of the file which originally caused the collision. */
-static int
-FcDirCacheOpen (const FcChar8 *dir)
-{
- FcBool found;
- int fd = -1, collisions = 0;
- char *cache_file, *cache_hashed;
- char name_buf[FC_MAX_FILE_LEN];
- struct stat dir_stat;
-
- cache_file = (char *)FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE);
- if (!cache_file)
- return -1;
-
- fd = open(cache_file, O_RDONLY);
- if (fd != -1)
- return fd;
-
- if (stat ((char *)dir, &dir_stat) == -1)
- return -1;
-
- do
- {
- struct stat c;
- FcChar8 * name_buf_dir;
-
- cache_hashed = FcDirCacheHashName (cache_file, collisions++);
- if (!cache_hashed)
- return -1;
-
- if (fd > 0)
- close (fd);
- fd = open(cache_hashed, O_RDONLY);
- FcStrFree ((FcChar8 *)cache_hashed);
-
- if (fd == -1)
- return -1;
- FcCacheReadString (fd, name_buf, sizeof (name_buf));
- if (!strlen(name_buf))
- goto bail;
-
- name_buf_dir = FcStrDirname ((FcChar8 *)name_buf);
- if (stat ((char *)name_buf_dir, &c) == -1)
- {
- FcStrFree (name_buf_dir);
- continue;
- }
- FcStrFree (name_buf_dir);
- found = c.st_ino == dir_stat.st_ino;
- } while (!found);
- return fd;
-
- bail:
- close (fd);
- return -1;
-}
-
-/* read serialized state from the cache file */
-FcBool
-FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir, FcConfig *config)
-{
- int fd;
- char *current_arch_machine_name;
- char candidate_arch_machine_name[9+MACHINE_SIGNATURE_SIZE];
- off_t current_arch_start = 0;
- char subdirName[FC_MAX_FILE_LEN + 1 + 12 + 1];
-
- fd = FcDirCacheOpen (dir);
- if (fd < 0)
- goto bail;
-
- current_arch_machine_name = FcCacheMachineSignature();
- current_arch_start = FcCacheSkipToArch(fd,
- current_arch_machine_name);
- if (current_arch_start < 0)
- goto bail1;
-
- lseek (fd, current_arch_start, SEEK_SET);
- if (FcCacheReadString (fd, candidate_arch_machine_name,
- sizeof (candidate_arch_machine_name)) == 0)
- goto bail1;
-
- while (strlen(FcCacheReadString (fd, subdirName, sizeof (subdirName))) > 0)
- FcStrSetAdd (dirs, (FcChar8 *)subdirName);
-
- if (!FcDirCacheConsume (fd, (const char *)dir, set, config))
- goto bail1;
-
- close(fd);
- return FcTrue;
-
- bail1:
- close (fd);
- bail:
- return FcFalse;
-}
-
-static FcBool
-FcDirCacheConsume (int fd, const char * dir, FcFontSet *set, FcConfig *config)
-{
- FcCache metadata;
- void * current_dir_block;
- off_t pos;
-
- read(fd, &metadata, sizeof(FcCache));
- if (metadata.magic != FC_CACHE_MAGIC)
- return FcFalse;
-
- if (!metadata.count)
- {
- pos = FcCacheNextOffset (lseek(fd, 0, SEEK_CUR));
- lseek (fd, pos, SEEK_SET);
- FcConfigAddFontDir (config, (FcChar8 *)dir);
- return FcTrue;
- }
-
- pos = FcCacheNextOffset (lseek(fd, 0, SEEK_CUR));
- current_dir_block = mmap (0, metadata.count,
- PROT_READ, MAP_SHARED, fd, pos);
- lseek (fd, pos+metadata.count, SEEK_SET);
- if (current_dir_block == MAP_FAILED)