test-migration.c revision a32e9e42
1/* 2 * fontconfig/test/test-migration.c 3 * 4 * Copyright © 2000 Keith Packard 5 * Copyright © 2013 Akira TAGOH 6 * 7 * Permission to use, copy, modify, distribute, and sell this software and its 8 * documentation for any purpose is hereby granted without fee, provided that 9 * the above copyright notice appear in all copies and that both that 10 * copyright notice and this permission notice appear in supporting 11 * documentation, and that the name of the author(s) not be used in 12 * advertising or publicity pertaining to distribution of the software without 13 * specific, written prior permission. The authors make no 14 * representations about the suitability of this software for any purpose. It 15 * is provided "as is" without express or implied warranty. 16 * 17 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23 * PERFORMANCE OF THIS SOFTWARE. 24 */ 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31#include <unistd.h> 32#include <sys/types.h> 33#include <dirent.h> 34#ifndef HAVE_STRUCT_DIRENT_D_TYPE 35#include <sys/types.h> 36#include <sys/stat.h> 37#include <unistd.h> 38#endif 39#include <fontconfig/fontconfig.h> 40 41#ifdef HAVE_MKDTEMP 42#define fc_mkdtemp mkdtemp 43#else 44char * 45fc_mkdtemp (char *template) 46{ 47 if (!mktemp (template) || mkdir (template, 0700)) 48 return NULL; 49 50 return template; 51} 52#endif 53 54FcBool 55mkdir_p(const char *dir) 56{ 57 char *parent; 58 FcBool ret; 59 60 if (strlen (dir) == 0) 61 return FcFalse; 62 parent = (char *) FcStrDirname ((const FcChar8 *)dir); 63 if (!parent) 64 return FcFalse; 65 if (access (parent, F_OK) == 0) 66 ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0; 67 else if (access (parent, F_OK) == -1) 68 ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0; 69 else 70 ret = FcFalse; 71 free (parent); 72 73 return ret; 74} 75 76FcBool 77unlink_dirs(const char *dir) 78{ 79 DIR *d = opendir (dir); 80 struct dirent *e; 81 size_t len = strlen (dir); 82 char *n = NULL; 83 FcBool ret = FcTrue; 84#ifndef HAVE_STRUCT_DIRENT_D_TYPE 85 struct stat statb; 86#endif 87 88 if (!d) 89 return FcFalse; 90 while ((e = readdir(d)) != NULL) 91 { 92 size_t l; 93 94 if (strcmp (e->d_name, ".") == 0 || 95 strcmp (e->d_name, "..") == 0) 96 continue; 97 l = strlen (e->d_name) + 1; 98 if (n) 99 free (n); 100 n = malloc (l + len + 1); 101 strcpy (n, dir); 102 n[len] = '/'; 103 strcpy (&n[len + 1], e->d_name); 104#ifdef HAVE_STRUCT_DIRENT_D_TYPE 105 if (e->d_type == DT_DIR) 106#else 107 if (stat (n, &statb) == -1) 108 { 109 fprintf (stderr, "E: %s\n", n); 110 ret = FcFalse; 111 break; 112 } 113 if (S_ISDIR (statb.st_mode)) 114#endif 115 { 116 if (!unlink_dirs (n)) 117 { 118 fprintf (stderr, "E: %s\n", n); 119 ret = FcFalse; 120 break; 121 } 122 } 123 else 124 { 125 if (unlink (n) == -1) 126 { 127 fprintf (stderr, "E: %s\n", n); 128 ret = FcFalse; 129 break; 130 } 131 } 132 } 133 if (n) 134 free (n); 135 closedir (d); 136 137 if (rmdir (dir) == -1) 138 { 139 fprintf (stderr, "E: %s\n", dir); 140 return FcFalse; 141 } 142 143 return ret; 144} 145 146int 147main(void) 148{ 149 char template[32] = "fontconfig-XXXXXXXX"; 150 char *tmp = fc_mkdtemp (template); 151 size_t len = strlen (tmp), xlen, dlen; 152 char xdg[256], confd[256], fn[256], nfn[256], ud[256], nud[256]; 153 int ret = -1; 154 FILE *fp; 155 char *content = "<fontconfig></fontconfig>"; 156 157 strcpy (xdg, tmp); 158 strcpy (&xdg[len], "/.config"); 159 setenv ("HOME", tmp, 1); 160 setenv ("XDG_CONFIG_HOME", xdg, 1); 161 xlen = strlen (xdg); 162 strcpy (confd, xdg); 163 strcpy (&confd[xlen], "/fontconfig"); 164 dlen = strlen (confd); 165 /* In case there are no configuration files nor directory */ 166 FcInit (); 167 if (access (confd, F_OK) == 0) 168 { 169 fprintf (stderr, "%s unexpectedly exists\n", confd); 170 goto bail; 171 } 172 FcFini (); 173 if (!unlink_dirs (tmp)) 174 { 175 fprintf (stderr, "Unable to clean up\n"); 176 goto bail; 177 } 178 /* In case there are the user configuration file */ 179 strcpy (fn, tmp); 180 strcpy (&fn[len], "/.fonts.conf"); 181 strcpy (nfn, confd); 182 strcpy (&nfn[dlen], "/fonts.conf"); 183 if (!mkdir_p (confd)) 184 { 185 fprintf (stderr, "Unable to create a config dir: %s\n", confd); 186 goto bail; 187 } 188 if ((fp = fopen (fn, "wb")) == NULL) 189 { 190 fprintf (stderr, "Unable to create a config file: %s\n", fn); 191 goto bail; 192 } 193 fwrite (content, sizeof (char), strlen (content), fp); 194 fclose (fp); 195 FcInit (); 196 if (access (nfn, F_OK) != 0) 197 { 198 fprintf (stderr, "migration failed for %s\n", nfn); 199 goto bail; 200 } 201 FcFini (); 202 if (!unlink_dirs (tmp)) 203 { 204 fprintf (stderr, "Unable to clean up\n"); 205 goto bail; 206 } 207 /* In case there are the user configuration dir */ 208 strcpy (ud, tmp); 209 strcpy (&ud[len], "/.fonts.conf.d"); 210 strcpy (nud, confd); 211 strcpy (&nud[dlen], "/conf.d"); 212 if (!mkdir_p (ud)) 213 { 214 fprintf (stderr, "Unable to create a config dir: %s\n", ud); 215 goto bail; 216 } 217 FcInit (); 218 if (access (nud, F_OK) != 0) 219 { 220 fprintf (stderr, "migration failed for %s\n", nud); 221 goto bail; 222 } 223 FcFini (); 224 225 ret = 0; 226bail: 227 unlink_dirs (tmp); 228 229 return ret; 230} 231