(root)/
fontconfig-2.14.2/
test/
test-d1f48f11.c
       1  /*
       2   * fontconfig/test/test-d1f48f11.c
       3   *
       4   * Copyright © 2000 Keith Packard
       5   * Copyright © 2018 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 <dirent.h>
      32  #include <errno.h>
      33  #ifdef HAVE_UNISTD_H
      34  #include <unistd.h>
      35  #endif
      36  #ifndef HAVE_STRUCT_DIRENT_D_TYPE
      37  #include <sys/types.h>
      38  #include <sys/stat.h>
      39  #endif
      40  #include <fontconfig/fontconfig.h>
      41  
      42  #ifdef _WIN32
      43  #  define FC_DIR_SEPARATOR         '\\'
      44  #  define FC_DIR_SEPARATOR_S       "\\"
      45  #else
      46  #  define FC_DIR_SEPARATOR         '/'
      47  #  define FC_DIR_SEPARATOR_S       "/"
      48  #endif
      49  
      50  #ifdef _WIN32
      51  #include <direct.h>
      52  #define mkdir(path,mode) _mkdir(path)
      53  
      54  int
      55  setenv(const char *name, const char *value, int o)
      56  {
      57      size_t len = strlen(name) + strlen(value) + 1;
      58      char *s = malloc(len+1);
      59      int ret;
      60  
      61      snprintf(s, len, "%s=%s", name, value);
      62      ret = _putenv(s);
      63      free(s);
      64      return ret;
      65  }
      66  #endif
      67  
      68  extern FcChar8 *FcConfigRealFilename (FcConfig *, FcChar8 *);
      69  extern FcChar8 *FcStrCanonFilename (const FcChar8 *);
      70  
      71  #ifdef HAVE_MKDTEMP
      72  #define fc_mkdtemp	mkdtemp
      73  #else
      74  char *
      75  fc_mkdtemp (char *template)
      76  {
      77      if (!mktemp (template) || mkdir (template, 0700))
      78  	return NULL;
      79  
      80      return template;
      81  }
      82  #endif
      83  
      84  FcBool
      85  mkdir_p (const char *dir)
      86  {
      87      char *parent;
      88      FcBool ret;
      89  
      90      if (strlen (dir) == 0)
      91  	return FcFalse;
      92      parent = (char *) FcStrDirname ((const FcChar8 *) dir);
      93      if (!parent)
      94  	return FcFalse;
      95      if (access (parent, F_OK) == 0)
      96  	ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0;
      97      else if (access (parent, F_OK) == -1)
      98  	ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0;
      99      else
     100  	ret = FcFalse;
     101      free (parent);
     102  
     103      return ret;
     104  }
     105  
     106  FcBool
     107  unlink_dirs (const char *dir)
     108  {
     109      DIR *d = opendir (dir);
     110      struct dirent *e;
     111      size_t len = strlen (dir);
     112      char *n = NULL;
     113      FcBool ret = FcTrue;
     114  #ifndef HAVE_STRUCT_DIRENT_D_TYPE
     115      struct stat statb;
     116  #endif
     117  
     118      if (!d)
     119  	return FcFalse;
     120      while ((e = readdir (d)) != NULL)
     121      {
     122  	size_t l;
     123  
     124  	if (strcmp (e->d_name, ".") == 0 ||
     125  	    strcmp (e->d_name, "..") == 0)
     126  	    continue;
     127  	l = strlen (e->d_name) + 1;
     128  	if (n)
     129  	    free (n);
     130  	n = malloc (l + len + 1);
     131  	if (!n)
     132  	{
     133  	    ret = FcFalse;
     134  	    break;
     135  	}
     136  	strcpy (n, dir);
     137  	n[len] = FC_DIR_SEPARATOR;
     138  	strcpy (&n[len + 1], e->d_name);
     139  #ifdef HAVE_STRUCT_DIRENT_D_TYPE
     140  	if (e->d_type == DT_DIR)
     141  #else
     142  	if (stat (n, &statb) == -1)
     143  	{
     144  	    fprintf (stderr, "E: %s\n", n);
     145  	    ret = FcFalse;
     146  	    break;
     147  	}
     148  	if (S_ISDIR (statb.st_mode))
     149  #endif
     150  	{
     151  	    if (!unlink_dirs (n))
     152  	    {
     153  		fprintf (stderr, "E: %s\n", n);
     154  		ret = FcFalse;
     155  		break;
     156  	    }
     157  	}
     158  	else
     159  	{
     160  	    if (unlink (n) == -1)
     161  	    {
     162  		fprintf (stderr, "E: %s\n", n);
     163  		ret = FcFalse;
     164  		break;
     165  	    }
     166  	}
     167      }
     168      if (n)
     169  	free (n);
     170      closedir (d);
     171  
     172      if (rmdir (dir) == -1)
     173      {
     174  	fprintf (stderr, "E: %s\n", dir);
     175  	return FcFalse;
     176      }
     177  
     178      return ret;
     179  }
     180  
     181  char template[512] = "/tmp/fc-d1f48f11-XXXXXX";
     182  char systempl[512] = "/tmp/fc-d1f48f11-XXXXXX";
     183  char *rootdir, *sysroot;
     184  
     185  int
     186  setup (char *dir)
     187  {
     188      FcChar8 *confdir = NULL, *availdir = NULL, *real = NULL, *link = NULL;
     189      FILE *fp;
     190      int ret = 1;
     191  
     192      confdir = FcStrBuildFilename (dir, "conf.d", NULL);
     193      availdir = FcStrBuildFilename (dir, "conf.avail", NULL);
     194      mkdir_p (confdir);
     195      mkdir_p (availdir);
     196      real = FcStrBuildFilename (availdir, "00-foo.conf", NULL);
     197      link = FcStrBuildFilename (confdir, "00-foo.conf", NULL);
     198      if (!real || !link)
     199      {
     200  	fprintf (stderr, "E: unable to allocate memory\n");
     201  	goto bail;
     202      }
     203      if ((fp = fopen (real, "wb")) == NULL)
     204      {
     205  	fprintf (stderr, "E: unable to open a file\n");
     206  	goto bail;
     207      }
     208      fprintf (fp, "%s", real);
     209      fclose (fp);
     210      if (symlink ("../conf.avail/00-foo.conf", link) != 0)
     211      {
     212  	fprintf (stderr, "%s: %s\n", link, strerror (errno));
     213  	goto bail;
     214      }
     215      ret = 0;
     216  bail:
     217      if (real)
     218  	free (real);
     219      if (link)
     220  	free (link);
     221      if (availdir)
     222  	free (availdir);
     223      if (confdir)
     224  	free (confdir);
     225  
     226      return ret;
     227  }
     228  
     229  void
     230  teardown (const char *dir)
     231  {
     232      unlink_dirs (dir);
     233  }
     234  
     235  int
     236  main (void)
     237  {
     238      FcConfig *cfg = NULL;
     239      FcChar8 *dc = NULL, *da = NULL, *d = NULL;
     240      FcChar8 *ds = NULL, *dsa = NULL, *dsac = NULL;
     241      int ret = 1;
     242  
     243      rootdir = fc_mkdtemp (template);
     244      if (!rootdir)
     245      {
     246  	fprintf (stderr, "%s: %s\n", template, strerror (errno));
     247  	return 1;
     248      }
     249      sysroot = fc_mkdtemp (systempl);
     250      if (!sysroot)
     251      {
     252  	fprintf (stderr, "%s: %s\n", systempl, strerror (errno));
     253  	return 1;
     254      }
     255      ds = FcStrBuildFilename (sysroot, rootdir, NULL);
     256      
     257      if (setup (rootdir) != 0)
     258  	goto bail;
     259      if (setup (ds) != 0)
     260  	goto bail;
     261  
     262      dc = FcStrBuildFilename (rootdir, "conf.d", "00-foo.conf", NULL);
     263      da = FcStrBuildFilename (rootdir, "conf.avail", "00-foo.conf", NULL);
     264      cfg = FcConfigCreate ();
     265      d = FcConfigRealFilename (cfg, dc);
     266      if (strcmp ((const char *)d, (const char *)da) != 0)
     267      {
     268  	fprintf (stderr, "E: failed to compare for non-sysroot: %s, %s\n", d, da);
     269  	goto bail;
     270      }
     271  
     272      free (d);
     273      FcConfigDestroy (cfg);
     274      setenv ("FONTCONFIG_SYSROOT", sysroot, 1);
     275      cfg = FcConfigCreate ();
     276      dsa = FcStrBuildFilename (sysroot, da, NULL);
     277      dsac = FcStrCanonFilename (dsa);
     278      d = FcConfigRealFilename (cfg, dc);
     279      if (strcmp ((const char *)d, (const char *)dsac) != 0)
     280      {
     281  	fprintf (stderr, "E: failed to compare for sysroot: %s, %s\n", d, dsac);
     282  	goto bail;
     283      }
     284  
     285      ret = 0;
     286  bail:
     287      if (cfg)
     288  	FcConfigDestroy (cfg);
     289      if (ds)
     290  	free (ds);
     291      if (dsa)
     292  	free (dsa);
     293      if (dsac)
     294  	free (dsac);
     295      if (dc)
     296  	free (dc);
     297      if (da)
     298  	free (da);
     299      if (d)
     300  	free (d);
     301      teardown (sysroot);
     302      teardown (rootdir);
     303  
     304      return ret;
     305  }