test-issue110.c revision a4e54154
1a4e54154Smrg/* 2a4e54154Smrg * fontconfig/test/test-issue110.c 3a4e54154Smrg * 4a4e54154Smrg * Copyright © 2000 Keith Packard 5a4e54154Smrg * Copyright © 2018 Akira TAGOH 6a4e54154Smrg * 7a4e54154Smrg * Permission to use, copy, modify, distribute, and sell this software and its 8a4e54154Smrg * documentation for any purpose is hereby granted without fee, provided that 9a4e54154Smrg * the above copyright notice appear in all copies and that both that 10a4e54154Smrg * copyright notice and this permission notice appear in supporting 11a4e54154Smrg * documentation, and that the name of the author(s) not be used in 12a4e54154Smrg * advertising or publicity pertaining to distribution of the software without 13a4e54154Smrg * specific, written prior permission. The authors make no 14a4e54154Smrg * representations about the suitability of this software for any purpose. It 15a4e54154Smrg * is provided "as is" without express or implied warranty. 16a4e54154Smrg * 17a4e54154Smrg * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18a4e54154Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19a4e54154Smrg * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20a4e54154Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21a4e54154Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22a4e54154Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23a4e54154Smrg * PERFORMANCE OF THIS SOFTWARE. 24a4e54154Smrg */ 25a4e54154Smrg#ifdef HAVE_CONFIG_H 26a4e54154Smrg#include "config.h" 27a4e54154Smrg#endif 28a4e54154Smrg#include <stdio.h> 29a4e54154Smrg#include <stdlib.h> 30a4e54154Smrg#include <string.h> 31a4e54154Smrg#include <dirent.h> 32a4e54154Smrg#include <errno.h> 33a4e54154Smrg#ifdef HAVE_UNISTD_H 34a4e54154Smrg#include <unistd.h> 35a4e54154Smrg#endif 36a4e54154Smrg#ifndef HAVE_STRUCT_DIRENT_D_TYPE 37a4e54154Smrg#include <sys/types.h> 38a4e54154Smrg#include <sys/stat.h> 39a4e54154Smrg#endif 40a4e54154Smrg#include <fontconfig/fontconfig.h> 41a4e54154Smrg 42a4e54154Smrg#ifdef _WIN32 43a4e54154Smrg# define FC_DIR_SEPARATOR '\\' 44a4e54154Smrg# define FC_DIR_SEPARATOR_S "\\" 45a4e54154Smrg#else 46a4e54154Smrg# define FC_DIR_SEPARATOR '/' 47a4e54154Smrg# define FC_DIR_SEPARATOR_S "/" 48a4e54154Smrg#endif 49a4e54154Smrg 50a4e54154Smrg#ifdef _WIN32 51a4e54154Smrg#include <direct.h> 52a4e54154Smrg#define mkdir(path,mode) _mkdir(path) 53a4e54154Smrg 54a4e54154Smrgint 55a4e54154Smrgsetenv(const char *name, const char *value, int o) 56a4e54154Smrg{ 57a4e54154Smrg size_t len = strlen(name) + strlen(value) + 1; 58a4e54154Smrg char *s = malloc(len+1); 59a4e54154Smrg int ret; 60a4e54154Smrg 61a4e54154Smrg snprintf(s, len, "%s=%s", name, value); 62a4e54154Smrg ret = _putenv(s); 63a4e54154Smrg free(s); 64a4e54154Smrg return ret; 65a4e54154Smrg} 66a4e54154Smrg#endif 67a4e54154Smrg 68a4e54154Smrgextern FcChar8 *FcConfigRealFilename (FcConfig *, FcChar8 *); 69a4e54154Smrg 70a4e54154Smrg#ifdef HAVE_MKDTEMP 71a4e54154Smrg#define fc_mkdtemp mkdtemp 72a4e54154Smrg#else 73a4e54154Smrgchar * 74a4e54154Smrgfc_mkdtemp (char *template) 75a4e54154Smrg{ 76a4e54154Smrg if (!mktemp (template) || mkdir (template, 0700)) 77a4e54154Smrg return NULL; 78a4e54154Smrg 79a4e54154Smrg return template; 80a4e54154Smrg} 81a4e54154Smrg#endif 82a4e54154Smrg 83a4e54154SmrgFcBool 84a4e54154Smrgmkdir_p (const char *dir) 85a4e54154Smrg{ 86a4e54154Smrg char *parent; 87a4e54154Smrg FcBool ret; 88a4e54154Smrg 89a4e54154Smrg if (strlen (dir) == 0) 90a4e54154Smrg return FcFalse; 91a4e54154Smrg parent = (char *) FcStrDirname ((const FcChar8 *) dir); 92a4e54154Smrg if (!parent) 93a4e54154Smrg return FcFalse; 94a4e54154Smrg if (access (parent, F_OK) == 0) 95a4e54154Smrg ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0; 96a4e54154Smrg else if (access (parent, F_OK) == -1) 97a4e54154Smrg ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0; 98a4e54154Smrg else 99a4e54154Smrg ret = FcFalse; 100a4e54154Smrg free (parent); 101a4e54154Smrg 102a4e54154Smrg return ret; 103a4e54154Smrg} 104a4e54154Smrg 105a4e54154SmrgFcBool 106a4e54154Smrgunlink_dirs (const char *dir) 107a4e54154Smrg{ 108a4e54154Smrg DIR *d = opendir (dir); 109a4e54154Smrg struct dirent *e; 110a4e54154Smrg size_t len = strlen (dir); 111a4e54154Smrg char *n = NULL; 112a4e54154Smrg FcBool ret = FcTrue; 113a4e54154Smrg#ifndef HAVE_STRUCT_DIRENT_D_TYPE 114a4e54154Smrg struct stat statb; 115a4e54154Smrg#endif 116a4e54154Smrg 117a4e54154Smrg if (!d) 118a4e54154Smrg return FcFalse; 119a4e54154Smrg while ((e = readdir (d)) != NULL) 120a4e54154Smrg { 121a4e54154Smrg size_t l; 122a4e54154Smrg 123a4e54154Smrg if (strcmp (e->d_name, ".") == 0 || 124a4e54154Smrg strcmp (e->d_name, "..") == 0) 125a4e54154Smrg continue; 126a4e54154Smrg l = strlen (e->d_name) + 1; 127a4e54154Smrg if (n) 128a4e54154Smrg free (n); 129a4e54154Smrg n = malloc (l + len + 1); 130a4e54154Smrg if (!n) 131a4e54154Smrg { 132a4e54154Smrg ret = FcFalse; 133a4e54154Smrg break; 134a4e54154Smrg } 135a4e54154Smrg strcpy (n, dir); 136a4e54154Smrg n[len] = FC_DIR_SEPARATOR; 137a4e54154Smrg strcpy (&n[len + 1], e->d_name); 138a4e54154Smrg#ifdef HAVE_STRUCT_DIRENT_D_TYPE 139a4e54154Smrg if (e->d_type == DT_DIR) 140a4e54154Smrg#else 141a4e54154Smrg if (stat (n, &statb) == -1) 142a4e54154Smrg { 143a4e54154Smrg fprintf (stderr, "E: %s\n", n); 144a4e54154Smrg ret = FcFalse; 145a4e54154Smrg break; 146a4e54154Smrg } 147a4e54154Smrg if (S_ISDIR (statb.st_mode)) 148a4e54154Smrg#endif 149a4e54154Smrg { 150a4e54154Smrg if (!unlink_dirs (n)) 151a4e54154Smrg { 152a4e54154Smrg fprintf (stderr, "E: %s\n", n); 153a4e54154Smrg ret = FcFalse; 154a4e54154Smrg break; 155a4e54154Smrg } 156a4e54154Smrg } 157a4e54154Smrg else 158a4e54154Smrg { 159a4e54154Smrg if (unlink (n) == -1) 160a4e54154Smrg { 161a4e54154Smrg fprintf (stderr, "E: %s\n", n); 162a4e54154Smrg ret = FcFalse; 163a4e54154Smrg break; 164a4e54154Smrg } 165a4e54154Smrg } 166a4e54154Smrg } 167a4e54154Smrg if (n) 168a4e54154Smrg free (n); 169a4e54154Smrg closedir (d); 170a4e54154Smrg 171a4e54154Smrg if (rmdir (dir) == -1) 172a4e54154Smrg { 173a4e54154Smrg fprintf (stderr, "E: %s\n", dir); 174a4e54154Smrg return FcFalse; 175a4e54154Smrg } 176a4e54154Smrg 177a4e54154Smrg return ret; 178a4e54154Smrg} 179a4e54154Smrg 180a4e54154Smrgint 181a4e54154Smrgmain(void) 182a4e54154Smrg{ 183a4e54154Smrg FcConfig *cfg = FcConfigCreate (); 184a4e54154Smrg char *basedir, template[512] = "/tmp/fc110-XXXXXX"; 185a4e54154Smrg char *sysroot, systempl[512] = "/tmp/fc110-XXXXXX"; 186a4e54154Smrg FcChar8 *d = NULL; 187a4e54154Smrg FcChar8 *ret = NULL; 188a4e54154Smrg FcChar8 *s = NULL; 189a4e54154Smrg FILE *fp; 190a4e54154Smrg int retval = 0; 191a4e54154Smrg 192a4e54154Smrg retval++; 193a4e54154Smrg basedir = fc_mkdtemp (template); 194a4e54154Smrg if (!basedir) 195a4e54154Smrg { 196a4e54154Smrg fprintf (stderr, "%s: %s\n", template, strerror (errno)); 197a4e54154Smrg goto bail; 198a4e54154Smrg } 199a4e54154Smrg retval++; 200a4e54154Smrg sysroot = fc_mkdtemp (systempl); 201a4e54154Smrg if (!sysroot) 202a4e54154Smrg { 203a4e54154Smrg fprintf (stderr, "%s: %s\n", systempl, strerror (errno)); 204a4e54154Smrg goto bail; 205a4e54154Smrg } 206a4e54154Smrg fprintf (stderr, "D: Creating %s\n", basedir); 207a4e54154Smrg mkdir_p (basedir); 208a4e54154Smrg setenv ("HOME", basedir, 1); 209a4e54154Smrg retval++; 210a4e54154Smrg s = FcStrBuildFilename (basedir, ".fonts.conf", NULL); 211a4e54154Smrg if (!s) 212a4e54154Smrg goto bail; 213a4e54154Smrg retval++; 214a4e54154Smrg fprintf (stderr, "D: Creating %s\n", s); 215a4e54154Smrg if ((fp = fopen (s, "wb")) == NULL) 216a4e54154Smrg goto bail; 217a4e54154Smrg fprintf (fp, "%s", s); 218a4e54154Smrg fclose (fp); 219a4e54154Smrg retval++; 220a4e54154Smrg fprintf (stderr, "D: Checking file path\n"); 221a4e54154Smrg ret = FcConfigRealFilename (cfg, "~/.fonts.conf"); 222a4e54154Smrg if (!ret) 223a4e54154Smrg goto bail; 224a4e54154Smrg retval++; 225a4e54154Smrg if (strcmp ((const char *) s, (const char *) ret) != 0) 226a4e54154Smrg goto bail; 227a4e54154Smrg free (ret); 228a4e54154Smrg free (s); 229a4e54154Smrg FcConfigDestroy (cfg); 230a4e54154Smrg setenv ("FONTCONFIG_SYSROOT", sysroot, 1); 231a4e54154Smrg cfg = FcConfigCreate (); 232a4e54154Smrg fprintf (stderr, "D: Creating %s\n", sysroot); 233a4e54154Smrg mkdir_p (sysroot); 234a4e54154Smrg retval++; 235a4e54154Smrg d = FcStrBuildFilename (sysroot, basedir, NULL); 236a4e54154Smrg fprintf (stderr, "D: Creating %s\n", d); 237a4e54154Smrg mkdir_p (d); 238a4e54154Smrg free (d); 239a4e54154Smrg s = FcStrBuildFilename (sysroot, basedir, ".fonts.conf", NULL); 240a4e54154Smrg if (!s) 241a4e54154Smrg goto bail; 242a4e54154Smrg retval++; 243a4e54154Smrg fprintf (stderr, "D: Creating %s\n", s); 244a4e54154Smrg if ((fp = fopen (s, "wb")) == NULL) 245a4e54154Smrg goto bail; 246a4e54154Smrg fprintf (fp, "%s", s); 247a4e54154Smrg fclose (fp); 248a4e54154Smrg retval++; 249a4e54154Smrg fprintf (stderr, "D: Checking file path\n"); 250a4e54154Smrg ret = FcConfigRealFilename (cfg, "~/.fonts.conf"); 251a4e54154Smrg if (!ret) 252a4e54154Smrg goto bail; 253a4e54154Smrg retval++; 254a4e54154Smrg if (strcmp ((const char *) s, (const char *) ret) != 0) 255a4e54154Smrg goto bail; 256a4e54154Smrg retval = 0; 257a4e54154Smrgbail: 258a4e54154Smrg fprintf (stderr, "Cleaning up\n"); 259a4e54154Smrg unlink_dirs (basedir); 260a4e54154Smrg if (ret) 261a4e54154Smrg free (ret); 262a4e54154Smrg if (s) 263a4e54154Smrg free (s); 264a4e54154Smrg 265a4e54154Smrg return retval; 266a4e54154Smrg} 267a4e54154Smrg 268