+2006-01-26 Patirck Lam <plam@mit.edu>
+ * src/fccache.c (FcGlobalCacheSave, FcDirCacheWrite):
+ * src/fccfg.c (FcConfigAddFontDirSubdirs, FcConfigNormalizeFontDir):
+ * src/fcdir.c (FcDirScanConfig):
+ * src/fcxml.c (FcEndElement):
+
+ Stop trampling the directory name when writing out caches.
+ (with Mike Fabian:) Beef up FcConfigNormalizeFontDir to scan
+ subdirs when necessary. Don't scan directories that can't be
+ normalized.
+
2006-01-25 Patrick Lam <plam@mit.edu>
* src/fccache.c (FcDirCacheOpen, FcDirCacheWrite):
* src/fccfg.c (FcConfigEvaluate):
S_IRUSR | S_IWUSR);
if (fd == -1)
goto bail2;
+ FcCacheWriteString (fd, FC_GLOBAL_MAGIC_COOKIE);
fd_orig = open ((char *) FcAtomicOrigFile(atomic), O_RDONLY);
current_arch_machine_name);
if (current_arch_start < 0)
- current_arch_start = FcCacheNextOffset (lseek(fd_orig, 0, SEEK_END));
+ {
+ off_t i = lseek(fd_orig, 0, SEEK_END);
+ if (i < strlen (FC_GLOBAL_MAGIC_COOKIE)+1)
+ i = strlen (FC_GLOBAL_MAGIC_COOKIE)+1;
+ current_arch_start = FcCacheNextOffset (i);
+ }
if (!FcCacheCopyOld(fd, fd_orig, current_arch_start))
goto bail3;
}
truncate_to -= current_arch_start;
- FcCacheWriteString (fd, FC_GLOBAL_MAGIC_COOKIE);
sprintf (header, "%8x ", (int)truncate_to);
strcat (header, current_arch_machine_name);
if (!FcCacheWriteString (fd, header))
FcCacheSkipToArch(fd_orig, current_arch_machine_name);
if (current_arch_start < 0)
- current_arch_start = FcCacheNextOffset (lseek(fd_orig, 0, SEEK_END));
+ {
+ off_t i = lseek(fd_orig, 0, SEEK_END);
+ if (i < strlen (FC_GLOBAL_MAGIC_COOKIE)+1)
+ i = strlen (FC_GLOBAL_MAGIC_COOKIE)+1;
+ current_arch_start = FcCacheNextOffset (i);
+ }
if (fd_orig != -1 && !FcCacheCopyOld(fd, fd_orig, current_arch_start))
goto bail4;
* PERFORMANCE OF THIS SOFTWARE.
*/
+#include <dirent.h>
+#include <sys/types.h>
#include "fcint.h"
#if defined (_WIN32) && (defined (PIC) || defined (DLL_EXPORT))
return FcStrSetAddFilename (config->fontDirs, d);
}
+static FcBool
+FcConfigAddFontDirSubdirs (FcConfig *config,
+ const FcChar8 *d)
+{
+ DIR *dir;
+ struct dirent *e;
+ FcChar8 *subdir;
+
+ if (!(dir = opendir ((char *) d)))
+ return FcFalse;
+ if (!(subdir = (FcChar8 *) malloc (strlen ((char *) d) + FC_MAX_FILE_LEN + 2)))
+ {
+ fprintf (stderr, "out of memory");
+ return FcFalse;
+ }
+ while ((e = readdir (dir)))
+ {
+ if (strcmp (e->d_name, ".") && strcmp (e->d_name, "..") &&
+ strlen (e->d_name) < FC_MAX_FILE_LEN)
+ {
+ strcpy ((char *)subdir, (char *)d);
+ strcat ((char *)subdir, "/");
+ strcat ((char *)subdir, e->d_name);
+ if (FcFileIsDir (subdir))
+ {
+ FcConfigAddFontDir (config, subdir);
+ FcConfigAddFontDirSubdirs (config, subdir);
+ }
+ }
+ }
+ free (subdir);
+ closedir (dir);
+ return FcTrue;
+}
+
const FcChar8 *
FcConfigNormalizeFontDir (FcConfig *config,
const FcChar8 *d)
if (di == s.st_ino && dd == s.st_dev)
return config->fontDirs->strs[n];
}
+
+ /* Ok, we didn't find it in fontDirs; let's add subdirs.... */
+ for (n = 0; n < config->fontDirs->num; n++)
+ FcConfigAddFontDirSubdirs (config, config->fontDirs->strs[n]);
+
+ /* ... and try again. */
+ for (n = 0; n < config->fontDirs->num; n++)
+ {
+ if (stat ((char *)config->fontDirs->strs[n], &s) == -1)
+ continue;
+ if (di == s.st_ino && dd == s.st_dev)
+ return config->fontDirs->strs[n];
+ }
+
+ /* if it fails, then really give up. */
return 0;
}
return FcTrue;
if (config)
- FcConfigAddFontDir (config, dir);
+ dir = FcConfigNormalizeFontDir (config, dir);
+
+ /* refuse to scan a directory that can't be normalized. */
+ if (!dir)
+ return FcFalse;
if (!force)
{
if (!FcStrUsesHome (data) || FcConfigHome ())
{
if (!FcConfigAddDir (parse->config, data))
- FcConfigMessage (parse, FcSevereError, "out of memory");
+ FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", data);
}
FcStrFree (data);
break;