diff --git a/src/fccache.c b/src/fccache.c index 9f1c298..e02d49e 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -830,34 +830,6 @@ bail1: return NULL; } - -#ifdef _WIN32 -#include -#define mkdir(path,mode) _mkdir(path) -#endif - -static FcBool -FcMakeDirectory (const FcChar8 *dir) -{ - FcChar8 *parent; - FcBool ret; - - if (strlen ((char *) dir) == 0) - return FcFalse; - - parent = FcStrDirname (dir); - if (!parent) - return FcFalse; - if (access ((char *) parent, F_OK) == 0) - ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0; - else if (access ((char *) parent, F_OK) == -1) - ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0; - else - ret = FcFalse; - FcStrFree (parent); - return ret; -} - /* write serialized state to the cache file */ FcBool FcDirCacheWrite (FcCache *cache, FcConfig *config) diff --git a/src/fccompat.c b/src/fccompat.c index a217160..d4f88c8 100644 --- a/src/fccompat.c +++ b/src/fccompat.c @@ -219,3 +219,30 @@ FcRandom(void) return result; } + +#ifdef _WIN32 +#include +#define mkdir(path,mode) _mkdir(path) +#endif + +FcBool +FcMakeDirectory (const FcChar8 *dir) +{ + FcChar8 *parent; + FcBool ret; + + if (strlen ((char *) dir) == 0) + return FcFalse; + + parent = FcStrDirname (dir); + if (!parent) + return FcFalse; + if (access ((char *) parent, F_OK) == 0) + ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0; + else if (access ((char *) parent, F_OK) == -1) + ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0; + else + ret = FcFalse; + FcStrFree (parent); + return ret; +} diff --git a/src/fcdir.c b/src/fcdir.c index dc580bb..b040a28 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -49,6 +49,16 @@ FcFileIsLink (const FcChar8 *file) #endif } +FcBool +FcFileIsFile (const FcChar8 *file) +{ + struct stat statb; + + if (FcStat (file, &statb) != 0) + return FcFalse; + return S_ISREG (statb.st_mode); +} + static FcBool FcFileScanFontConfig (FcFontSet *set, FcBlanks *blanks, diff --git a/src/fcint.h b/src/fcint.h index 52c47a1..ec0c674 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -747,6 +747,9 @@ FcMakeTempfile (char *template); FcPrivate int32_t FcRandom (void); +FcPrivate FcBool +FcMakeDirectory (const FcChar8 *dir); + /* fcdbg.c */ FcPrivate void @@ -804,6 +807,9 @@ FcDefaultFini (void); FcPrivate FcBool FcFileIsLink (const FcChar8 *file); +FcPrivate FcBool +FcFileIsFile (const FcChar8 *file); + FcPrivate FcBool FcFileScanConfig (FcFontSet *set, FcStrSet *dirs, diff --git a/src/fcxml.c b/src/fcxml.c index 6a2af85..2cdf0ad 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -2182,6 +2182,8 @@ FcParseInclude (FcConfigParse *parse) FcBool ignore_missing = FcFalse; FcBool deprecated = FcFalse; FcChar8 *prefix = NULL, *p; + static FcChar8 *userdir = NULL; + static FcChar8 *userconf = NULL; s = FcStrBufDoneStatic (&parse->pstack->str); if (!s) @@ -2214,23 +2216,78 @@ FcParseInclude (FcConfigParse *parse) memcpy (&prefix[plen + 1], s, dlen); prefix[plen + 1 + dlen] = 0; s = prefix; + if (FcFileIsDir (s)) + { + userdir: + if (!userdir) + userdir = FcStrdup (s); + } + else if (FcFileIsFile (s)) + { + userconf: + if (!userconf) + userconf = FcStrdup (s); + } + else + { + /* No config dir nor file on the XDG directory spec compliant place + * so need to guess what it is supposed to be. + */ + FcChar8 *parent = FcStrDirname (s); + + if (!FcFileIsDir (parent)) + FcMakeDirectory (parent); + FcStrFree (parent); + if (FcStrStr (s, (const FcChar8 *)"conf.d") != NULL) + goto userdir; + else + goto userconf; + } } if (!FcConfigParseAndLoad (parse->config, s, !ignore_missing)) parse->error = FcTrue; +#ifndef _WIN32 else { FcChar8 *filename; + static FcBool warn_conf = FcFalse, warn_confd = FcFalse; filename = FcConfigFilename(s); if (deprecated == FcTrue && filename != NULL && !FcFileIsLink (filename)) { - FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated.", s); + if (FcFileIsDir (filename)) + { + if (FcFileIsDir (userdir) || + rename ((const char *)filename, (const char *)userdir) != 0 || + symlink ((const char *)userdir, (const char *)filename) != 0) + { + if (!warn_confd) + { + FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userdir); + warn_confd = FcTrue; + } + } + } + else + { + if (FcFileIsFile (userconf) || + rename ((const char *)filename, (const char *)userconf) != 0 || + symlink ((const char *)userconf, (const char *)filename) != 0) + { + if (!warn_conf) + { + FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userconf); + warn_conf = FcTrue; + } + } + } } if(filename) FcStrFree(filename); } +#endif FcStrBufDestroy (&parse->pstack->str); bail: