(root)/
fontconfig-2.14.2/
test/
test-issue110.c
       1  /*
       2   * fontconfig/test/test-issue110.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  
      70  #ifdef HAVE_MKDTEMP
      71  #define fc_mkdtemp	mkdtemp
      72  #else
      73  char *
      74  fc_mkdtemp (char *template)
      75  {
      76      if (!mktemp (template) || mkdir (template, 0700))
      77  	return NULL;
      78  
      79      return template;
      80  }
      81  #endif
      82  
      83  FcBool
      84  mkdir_p (const char *dir)
      85  {
      86      char *parent;
      87      FcBool ret;
      88  
      89      if (strlen (dir) == 0)
      90  	return FcFalse;
      91      parent = (char *) FcStrDirname ((const FcChar8 *) dir);
      92      if (!parent)
      93  	return FcFalse;
      94      if (access (parent, F_OK) == 0)
      95  	ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0;
      96      else if (access (parent, F_OK) == -1)
      97  	ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0;
      98      else
      99  	ret = FcFalse;
     100      free (parent);
     101  
     102      return ret;
     103  }
     104  
     105  FcBool
     106  unlink_dirs (const char *dir)
     107  {
     108      DIR *d = opendir (dir);
     109      struct dirent *e;
     110      size_t len = strlen (dir);
     111      char *n = NULL;
     112      FcBool ret = FcTrue;
     113  #ifndef HAVE_STRUCT_DIRENT_D_TYPE
     114      struct stat statb;
     115  #endif
     116  
     117      if (!d)
     118  	return FcFalse;
     119      while ((e = readdir (d)) != NULL)
     120      {
     121  	size_t l;
     122  
     123  	if (strcmp (e->d_name, ".") == 0 ||
     124  	    strcmp (e->d_name, "..") == 0)
     125  	    continue;
     126  	l = strlen (e->d_name) + 1;
     127  	if (n)
     128  	    free (n);
     129  	n = malloc (l + len + 1);
     130  	if (!n)
     131  	{
     132  	    ret = FcFalse;
     133  	    break;
     134  	}
     135  	strcpy (n, dir);
     136  	n[len] = FC_DIR_SEPARATOR;
     137  	strcpy (&n[len + 1], e->d_name);
     138  #ifdef HAVE_STRUCT_DIRENT_D_TYPE
     139  	if (e->d_type == DT_DIR)
     140  #else
     141  	if (stat (n, &statb) == -1)
     142  	{
     143  	    fprintf (stderr, "E: %s\n", n);
     144  	    ret = FcFalse;
     145  	    break;
     146  	}
     147  	if (S_ISDIR (statb.st_mode))
     148  #endif
     149  	{
     150  	    if (!unlink_dirs (n))
     151  	    {
     152  		fprintf (stderr, "E: %s\n", n);
     153  		ret = FcFalse;
     154  		break;
     155  	    }
     156  	}
     157  	else
     158  	{
     159  	    if (unlink (n) == -1)
     160  	    {
     161  		fprintf (stderr, "E: %s\n", n);
     162  		ret = FcFalse;
     163  		break;
     164  	    }
     165  	}
     166      }
     167      if (n)
     168  	free (n);
     169      closedir (d);
     170  
     171      if (rmdir (dir) == -1)
     172      {
     173  	fprintf (stderr, "E: %s\n", dir);
     174  	return FcFalse;
     175      }
     176  
     177      return ret;
     178  }
     179  
     180  int
     181  main(void)
     182  {
     183      FcConfig *cfg = FcConfigCreate ();
     184      char *basedir, template[512] = "/tmp/fc110-XXXXXX";
     185      char *sysroot, systempl[512] = "/tmp/fc110-XXXXXX";
     186      FcChar8 *d = NULL;
     187      FcChar8 *ret = NULL;
     188      FcChar8 *s = NULL;
     189      FILE *fp;
     190      int retval = 0;
     191  
     192      retval++;
     193      basedir = fc_mkdtemp (template);
     194      if (!basedir)
     195      {
     196  	fprintf (stderr, "%s: %s\n", template, strerror (errno));
     197  	goto bail;
     198      }
     199      retval++;
     200      sysroot = fc_mkdtemp (systempl);
     201      if (!sysroot)
     202      {
     203  	fprintf (stderr, "%s: %s\n", systempl, strerror (errno));
     204  	goto bail;
     205      }
     206      fprintf (stderr, "D: Creating %s\n", basedir);
     207      mkdir_p (basedir);
     208      setenv ("HOME", basedir, 1);
     209      retval++;
     210      s = FcStrBuildFilename (basedir, ".fonts.conf", NULL);
     211      if (!s)
     212  	goto bail;
     213      retval++;
     214      fprintf (stderr, "D: Creating %s\n", s);
     215      if ((fp = fopen (s, "wb")) == NULL)
     216  	goto bail;
     217      fprintf (fp, "%s", s);
     218      fclose (fp);
     219      retval++;
     220      fprintf (stderr, "D: Checking file path\n");
     221      ret = FcConfigRealFilename (cfg, "~/.fonts.conf");
     222      if (!ret)
     223  	goto bail;
     224      retval++;
     225      if (strcmp ((const char *) s, (const char *) ret) != 0)
     226  	goto bail;
     227      free (ret);
     228      free (s);
     229      FcConfigDestroy (cfg);
     230      setenv ("FONTCONFIG_SYSROOT", sysroot, 1);
     231      cfg = FcConfigCreate ();
     232      fprintf (stderr, "D: Creating %s\n", sysroot);
     233      mkdir_p (sysroot);
     234      retval++;
     235      d = FcStrBuildFilename (sysroot, basedir, NULL);
     236      fprintf (stderr, "D: Creating %s\n", d);
     237      mkdir_p (d);
     238      free (d);
     239      s = FcStrBuildFilename (sysroot, basedir, ".fonts.conf", NULL);
     240      if (!s)
     241  	goto bail;
     242      retval++;
     243      fprintf (stderr, "D: Creating %s\n", s);
     244      if ((fp = fopen (s, "wb")) == NULL)
     245  	goto bail;
     246      fprintf (fp, "%s", s);
     247      fclose (fp);
     248      retval++;
     249      fprintf (stderr, "D: Checking file path\n");
     250      ret = FcConfigRealFilename (cfg, "~/.fonts.conf");
     251      if (!ret)
     252  	goto bail;
     253      retval++;
     254      if (strcmp ((const char *) s, (const char *) ret) != 0)
     255  	goto bail;
     256      retval = 0;
     257  bail:
     258      fprintf (stderr, "Cleaning up\n");
     259      unlink_dirs (basedir);
     260      if (ret)
     261  	free (ret);
     262      if (s)
     263  	free (s);
     264  
     265      return retval;
     266  }
     267