]> git.wh0rd.org - fontconfig.git/blobdiff - src/fccache.c
fc-cache: add a --root option
[fontconfig.git] / src / fccache.c
index 571aa6403f1f0ca2d07cbc53c1f9a817e70680d0..01ae89f0435b6bfedda14101b12004887dcc7284 100644 (file)
@@ -6,9 +6,9 @@
  * documentation for any purpose is hereby granted without fee, provided that
  * the above copyright notice appear in all copies and that both that
  * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
+ * documentation, and that the name of the author(s) not be used in
  * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
+ * specific, written prior permission.  The authors make no
  * representations about the suitability of this software for any purpose.  It
  * is provided "as is" without express or implied warranty.
  *
@@ -22,7 +22,7 @@
  */
 
 #include "fcint.h"
-#include "../fc-arch/fcarch.h"
+#include "fcarch.h"
 #include <stdio.h>
 #include <fcntl.h>
 #include <dirent.h>
@@ -41,6 +41,7 @@
 #define O_BINARY 0
 #endif
 
+
 struct MD5Context {
         FcChar32 buf[4];
         FcChar32 bits[2];
@@ -86,7 +87,7 @@ typedef __int64 INT64;
  */
 
 int
-FcStat (const char *file, struct stat *statb)
+FcStat (const FcChar8 *file, struct stat *statb)
 {
     WIN32_FILE_ATTRIBUTE_DATA wfad;
     char full_path_name[MAX_PATH];
@@ -131,6 +132,24 @@ FcStat (const char *file, struct stat *statb)
 
     return 0;
 }
+
+#else
+
+int
+FcStat (const FcChar8 *file, struct stat *statb)
+{
+    int ret;
+    FcChar8 *fullFile = FcConfigGetRootPlus (file);
+
+    if (fullFile)
+       file = fullFile;
+    ret = stat ((char *) file, statb);
+    if (fullFile)
+       FcStrFree (fullFile);
+
+    return ret;
+}
+
 #endif
 
 static const char bin2hex[] = { '0', '1', '2', '3',
@@ -197,12 +216,18 @@ static int
 FcDirCacheOpenFile (const FcChar8 *cache_file, struct stat *file_stat)
 {
     int        fd;
+    FcChar8 *fullFile;
 
 #ifdef _WIN32
     if (FcStat (cache_file, file_stat) < 0)
         return -1;
 #endif
-    fd = open((char *) cache_file, O_RDONLY | O_BINARY);
+    fullFile = FcConfigGetRootPlus (cache_file);
+    if (fullFile)
+       cache_file = fullFile;
+    fd = open ((char *) cache_file, O_RDONLY | O_BINARY);
+    if (fullFile)
+       FcStrFree (fullFile);
     if (fd < 0)
        return fd;
 #ifndef _WIN32
@@ -233,7 +258,7 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
     struct stat file_stat, dir_stat;
     FcBool     ret = FcFalse;
 
-    if (FcStat ((char *) dir, &dir_stat) < 0)
+    if (FcStat (dir, &dir_stat) < 0)
         return FcFalse;
 
     FcDirCacheBasename (dir, cache_base);
@@ -515,7 +540,7 @@ FcCacheTimeValid (FcCache *cache, struct stat *dir_stat)
 
     if (!dir_stat)
     {
-       if (FcStat ((const char *) FcCacheDir (cache), &dir_static) < 0)
+       if (FcStat (FcCacheDir (cache), &dir_static) < 0)
            return FcFalse;
        dir_stat = &dir_static;
     }
@@ -717,8 +742,6 @@ FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcSt
     FcSerialize        *serialize = FcSerializeCreate ();
     FcCache *cache;
     int i;
-    intptr_t   cache_offset;
-    intptr_t   dirs_offset;
     FcChar8    *dir_serialize;
     intptr_t   *dirs_serialize;
     FcFontSet  *set_serialize;
@@ -728,7 +751,7 @@ FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcSt
     /*
      * Space for cache structure
      */
-    cache_offset = FcSerializeReserve (serialize, sizeof (FcCache));
+    FcSerializeReserve (serialize, sizeof (FcCache));
     /*
      * Directory name
      */
@@ -737,7 +760,7 @@ FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcSt
     /*
      * Subdirs
      */
-    dirs_offset = FcSerializeAlloc (serialize, dirs, dirs->num * sizeof (FcChar8 *));
+    FcSerializeAlloc (serialize, dirs, dirs->num * sizeof (FcChar8 *));
     for (i = 0; i < dirs->num; i++)
        if (!FcStrSerializeAlloc (serialize, dirs->strs[i]))
            goto bail1;
@@ -846,6 +869,8 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
     FcStrList      *list;
     FcChar8        *cache_dir = NULL;
     FcChar8        *test_dir;
+    FcChar8        *full_test_dir;
+    FcBool         free_test_dir;
     FcCacheSkip     *skip;
     struct stat     cache_stat;
     int                    magic;
@@ -858,7 +883,19 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
     list = FcStrListCreate (config->cacheDirs);
     if (!list)
        return FcFalse;
+    free_test_dir = FcFalse;
     while ((test_dir = FcStrListNext (list))) {
+       if (free_test_dir)
+           FcStrFree (full_test_dir);
+       free_test_dir = FcFalse;
+
+       full_test_dir = FcConfigGetRootPlus (test_dir);
+       if (full_test_dir)
+       {
+           free_test_dir = FcTrue;
+           test_dir = full_test_dir;
+       }
+
        if (access ((char *) test_dir, W_OK|X_OK) == 0)
        {
            cache_dir = test_dir;
@@ -888,12 +925,12 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
     }
     FcStrListDone (list);
     if (!cache_dir)
-       return FcFalse;
+       goto bail0;
 
     FcDirCacheBasename (dir, cache_base);
     cache_hashed = FcStrPlus (cache_dir, cache_base);
     if (!cache_hashed)
-        return FcFalse;
+        goto bail0;
 
     if (FcDebug () & FC_DBG_CACHE)
         printf ("FcDirCacheWriteDir dir \"%s\" file \"%s\"\n",
@@ -960,6 +997,9 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
     FcAtomicDestroy (atomic);
  bail1:
     FcStrFree (cache_hashed);
+ bail0:
+    if (free_test_dir)
+       FcStrFree (full_test_dir);
     return FcFalse;
 }
 
@@ -1157,7 +1197,7 @@ static void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
     MD5Transform(ctx->buf, (FcChar32 *) ctx->in);
     byteReverse((unsigned char *) ctx->buf, 4);
     memcpy(digest, ctx->buf, 16);
-    memset(ctx, 0, sizeof(ctx));        /* In case it's sensitive */
+    memset(ctx, 0, sizeof(*ctx));        /* In case it's sensitive */
 }