1b09479dcSmrg/* 2b09479dcSmrg * fontconfig/test/test-migration.c 3b09479dcSmrg * 4b09479dcSmrg * Copyright © 2000 Keith Packard 5b09479dcSmrg * Copyright © 2013 Akira TAGOH 6b09479dcSmrg * 7b09479dcSmrg * Permission to use, copy, modify, distribute, and sell this software and its 8b09479dcSmrg * documentation for any purpose is hereby granted without fee, provided that 9b09479dcSmrg * the above copyright notice appear in all copies and that both that 10b09479dcSmrg * copyright notice and this permission notice appear in supporting 11b09479dcSmrg * documentation, and that the name of the author(s) not be used in 12b09479dcSmrg * advertising or publicity pertaining to distribution of the software without 13b09479dcSmrg * specific, written prior permission. The authors make no 14b09479dcSmrg * representations about the suitability of this software for any purpose. It 15b09479dcSmrg * is provided "as is" without express or implied warranty. 16b09479dcSmrg * 17b09479dcSmrg * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18b09479dcSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19b09479dcSmrg * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20b09479dcSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21b09479dcSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22b09479dcSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23b09479dcSmrg * PERFORMANCE OF THIS SOFTWARE. 24b09479dcSmrg */ 25a32e9e42Smrg#ifdef HAVE_CONFIG_H 26a32e9e42Smrg#include "config.h" 27a32e9e42Smrg#endif 286fc018e4Smrg#include <stdio.h> 296fc018e4Smrg#include <stdlib.h> 306fc018e4Smrg#include <string.h> 316fc018e4Smrg#include <sys/types.h> 326fc018e4Smrg#include <dirent.h> 33a4e54154Smrg#ifdef HAVE_UNISTD_H 34a4e54154Smrg#include <unistd.h> 35a4e54154Smrg#endif 36b09479dcSmrg#ifndef HAVE_STRUCT_DIRENT_D_TYPE 37b09479dcSmrg#include <sys/types.h> 38b09479dcSmrg#include <sys/stat.h> 39b09479dcSmrg#endif 406fc018e4Smrg#include <fontconfig/fontconfig.h> 416fc018e4Smrg 42b09479dcSmrg#ifdef HAVE_MKDTEMP 43b09479dcSmrg#define fc_mkdtemp mkdtemp 44b09479dcSmrg#else 45b09479dcSmrgchar * 46b09479dcSmrgfc_mkdtemp (char *template) 47b09479dcSmrg{ 48b09479dcSmrg if (!mktemp (template) || mkdir (template, 0700)) 49b09479dcSmrg return NULL; 50b09479dcSmrg 51b09479dcSmrg return template; 52b09479dcSmrg} 53b09479dcSmrg#endif 54b09479dcSmrg 556fc018e4SmrgFcBool 566fc018e4Smrgmkdir_p(const char *dir) 576fc018e4Smrg{ 586fc018e4Smrg char *parent; 596fc018e4Smrg FcBool ret; 606fc018e4Smrg 616fc018e4Smrg if (strlen (dir) == 0) 626fc018e4Smrg return FcFalse; 63953daebaSmrg parent = (char *) FcStrDirname ((const FcChar8 *)dir); 646fc018e4Smrg if (!parent) 656fc018e4Smrg return FcFalse; 666fc018e4Smrg if (access (parent, F_OK) == 0) 676fc018e4Smrg ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0; 686fc018e4Smrg else if (access (parent, F_OK) == -1) 696fc018e4Smrg ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0; 706fc018e4Smrg else 716fc018e4Smrg ret = FcFalse; 726fc018e4Smrg free (parent); 736fc018e4Smrg 746fc018e4Smrg return ret; 756fc018e4Smrg} 766fc018e4Smrg 776fc018e4SmrgFcBool 786fc018e4Smrgunlink_dirs(const char *dir) 796fc018e4Smrg{ 806fc018e4Smrg DIR *d = opendir (dir); 816fc018e4Smrg struct dirent *e; 826fc018e4Smrg size_t len = strlen (dir); 836fc018e4Smrg char *n = NULL; 846fc018e4Smrg FcBool ret = FcTrue; 85b09479dcSmrg#ifndef HAVE_STRUCT_DIRENT_D_TYPE 86b09479dcSmrg struct stat statb; 87b09479dcSmrg#endif 886fc018e4Smrg 896fc018e4Smrg if (!d) 906fc018e4Smrg return FcFalse; 916fc018e4Smrg while ((e = readdir(d)) != NULL) 926fc018e4Smrg { 936fc018e4Smrg size_t l; 946fc018e4Smrg 956fc018e4Smrg if (strcmp (e->d_name, ".") == 0 || 966fc018e4Smrg strcmp (e->d_name, "..") == 0) 976fc018e4Smrg continue; 986fc018e4Smrg l = strlen (e->d_name) + 1; 996fc018e4Smrg if (n) 1006fc018e4Smrg free (n); 1016fc018e4Smrg n = malloc (l + len + 1); 1026fc018e4Smrg strcpy (n, dir); 1036fc018e4Smrg n[len] = '/'; 1046fc018e4Smrg strcpy (&n[len + 1], e->d_name); 105b09479dcSmrg#ifdef HAVE_STRUCT_DIRENT_D_TYPE 1066fc018e4Smrg if (e->d_type == DT_DIR) 107b09479dcSmrg#else 108b09479dcSmrg if (stat (n, &statb) == -1) 109b09479dcSmrg { 110b09479dcSmrg fprintf (stderr, "E: %s\n", n); 111b09479dcSmrg ret = FcFalse; 112b09479dcSmrg break; 113b09479dcSmrg } 114b09479dcSmrg if (S_ISDIR (statb.st_mode)) 115b09479dcSmrg#endif 1166fc018e4Smrg { 1176fc018e4Smrg if (!unlink_dirs (n)) 1186fc018e4Smrg { 1196fc018e4Smrg fprintf (stderr, "E: %s\n", n); 1206fc018e4Smrg ret = FcFalse; 1216fc018e4Smrg break; 1226fc018e4Smrg } 1236fc018e4Smrg } 1246fc018e4Smrg else 1256fc018e4Smrg { 1266fc018e4Smrg if (unlink (n) == -1) 1276fc018e4Smrg { 1286fc018e4Smrg fprintf (stderr, "E: %s\n", n); 1296fc018e4Smrg ret = FcFalse; 1306fc018e4Smrg break; 1316fc018e4Smrg } 1326fc018e4Smrg } 1336fc018e4Smrg } 1346fc018e4Smrg if (n) 1356fc018e4Smrg free (n); 1366fc018e4Smrg closedir (d); 1376fc018e4Smrg 1386fc018e4Smrg if (rmdir (dir) == -1) 1396fc018e4Smrg { 1406fc018e4Smrg fprintf (stderr, "E: %s\n", dir); 1416fc018e4Smrg return FcFalse; 1426fc018e4Smrg } 1436fc018e4Smrg 1446fc018e4Smrg return ret; 1456fc018e4Smrg} 1466fc018e4Smrg 1476fc018e4Smrgint 1486fc018e4Smrgmain(void) 1496fc018e4Smrg{ 1506fc018e4Smrg char template[32] = "fontconfig-XXXXXXXX"; 151b09479dcSmrg char *tmp = fc_mkdtemp (template); 1526fc018e4Smrg size_t len = strlen (tmp), xlen, dlen; 1536fc018e4Smrg char xdg[256], confd[256], fn[256], nfn[256], ud[256], nud[256]; 1546fc018e4Smrg int ret = -1; 1556fc018e4Smrg FILE *fp; 1566fc018e4Smrg char *content = "<fontconfig></fontconfig>"; 1576fc018e4Smrg 1586fc018e4Smrg strcpy (xdg, tmp); 1596fc018e4Smrg strcpy (&xdg[len], "/.config"); 1606fc018e4Smrg setenv ("HOME", tmp, 1); 1616fc018e4Smrg setenv ("XDG_CONFIG_HOME", xdg, 1); 1626fc018e4Smrg xlen = strlen (xdg); 1636fc018e4Smrg strcpy (confd, xdg); 1646fc018e4Smrg strcpy (&confd[xlen], "/fontconfig"); 1656fc018e4Smrg dlen = strlen (confd); 1666fc018e4Smrg /* In case there are no configuration files nor directory */ 1676fc018e4Smrg FcInit (); 1686fc018e4Smrg if (access (confd, F_OK) == 0) 1696fc018e4Smrg { 1706fc018e4Smrg fprintf (stderr, "%s unexpectedly exists\n", confd); 1716fc018e4Smrg goto bail; 1726fc018e4Smrg } 1736fc018e4Smrg FcFini (); 1746fc018e4Smrg if (!unlink_dirs (tmp)) 1756fc018e4Smrg { 1766fc018e4Smrg fprintf (stderr, "Unable to clean up\n"); 1776fc018e4Smrg goto bail; 1786fc018e4Smrg } 1796fc018e4Smrg /* In case there are the user configuration file */ 1806fc018e4Smrg strcpy (fn, tmp); 1816fc018e4Smrg strcpy (&fn[len], "/.fonts.conf"); 1826fc018e4Smrg strcpy (nfn, confd); 1836fc018e4Smrg strcpy (&nfn[dlen], "/fonts.conf"); 1846fc018e4Smrg if (!mkdir_p (confd)) 1856fc018e4Smrg { 1866fc018e4Smrg fprintf (stderr, "Unable to create a config dir: %s\n", confd); 1876fc018e4Smrg goto bail; 1886fc018e4Smrg } 1896fc018e4Smrg if ((fp = fopen (fn, "wb")) == NULL) 1906fc018e4Smrg { 1916fc018e4Smrg fprintf (stderr, "Unable to create a config file: %s\n", fn); 1926fc018e4Smrg goto bail; 1936fc018e4Smrg } 1946fc018e4Smrg fwrite (content, sizeof (char), strlen (content), fp); 1956fc018e4Smrg fclose (fp); 1966fc018e4Smrg FcInit (); 1976fc018e4Smrg if (access (nfn, F_OK) != 0) 1986fc018e4Smrg { 1996fc018e4Smrg fprintf (stderr, "migration failed for %s\n", nfn); 2006fc018e4Smrg goto bail; 2016fc018e4Smrg } 2026fc018e4Smrg FcFini (); 2036fc018e4Smrg if (!unlink_dirs (tmp)) 2046fc018e4Smrg { 2056fc018e4Smrg fprintf (stderr, "Unable to clean up\n"); 2066fc018e4Smrg goto bail; 2076fc018e4Smrg } 2086fc018e4Smrg /* In case there are the user configuration dir */ 2096fc018e4Smrg strcpy (ud, tmp); 2106fc018e4Smrg strcpy (&ud[len], "/.fonts.conf.d"); 2116fc018e4Smrg strcpy (nud, confd); 2126fc018e4Smrg strcpy (&nud[dlen], "/conf.d"); 2136fc018e4Smrg if (!mkdir_p (ud)) 2146fc018e4Smrg { 2156fc018e4Smrg fprintf (stderr, "Unable to create a config dir: %s\n", ud); 2166fc018e4Smrg goto bail; 2176fc018e4Smrg } 2186fc018e4Smrg FcInit (); 2196fc018e4Smrg if (access (nud, F_OK) != 0) 2206fc018e4Smrg { 2216fc018e4Smrg fprintf (stderr, "migration failed for %s\n", nud); 2226fc018e4Smrg goto bail; 2236fc018e4Smrg } 2246fc018e4Smrg FcFini (); 2256fc018e4Smrg 2266fc018e4Smrg ret = 0; 2276fc018e4Smrgbail: 2286fc018e4Smrg unlink_dirs (tmp); 2296fc018e4Smrg 2306fc018e4Smrg return ret; 2316fc018e4Smrg} 232