(root)/
fontconfig-2.14.2/
test/
test-issue107.c
       1  /*
       2   * fontconfig/test/test-issue107.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 = NULL, template[512] = "/tmp/fc107-XXXXXX";
     185      char *sysroot = NULL, systempl[512] = "/tmp/fc107-XXXXXX";
     186      FcChar8 *d = NULL, *dd = NULL;
     187      FcCache *c = NULL;
     188      const FcChar8 *doc = (const FcChar8 *) ""
     189  	"<fontconfig>\n"
     190  	"  <dir>%s</dir>\n"
     191  	"</fontconfig>\n"
     192  	"";
     193      int retval = 0;
     194      size_t len;
     195  
     196      retval++;
     197      basedir = fc_mkdtemp (template);
     198      if (!basedir)
     199      {
     200  	fprintf (stderr, "%s: %s\n", template, strerror (errno));
     201  	goto bail;
     202      }
     203      retval++;
     204      sysroot = fc_mkdtemp (systempl);
     205      if (!sysroot)
     206      {
     207  	fprintf (stderr, "%s: %s\n", systempl, strerror (errno));
     208  	goto bail;
     209      }
     210      retval++;
     211      fprintf (stderr, "D: Creating %s\n", basedir);
     212      mkdir_p (basedir);
     213      len = strlen ((const char *) doc) + strlen (basedir) + 1;
     214      dd = malloc (len);
     215      snprintf ((char *) dd, len, (char *) doc, basedir);
     216      if (!FcConfigParseAndLoadFromMemory (cfg, dd, FcFalse))
     217      {
     218  	fprintf (stderr, "%s: Unable to load a config\n", basedir);
     219  	goto bail;
     220      }
     221      sleep (1);
     222      c = FcDirCacheRead ((const FcChar8 *) basedir, FcFalse, cfg);
     223      FcDirCacheUnload (c);
     224      sleep (1);
     225      retval++;
     226      if (!FcConfigUptoDate (cfg))
     227      {
     228  	fprintf (stderr, "updated. need to reload.\n");
     229  	goto bail;
     230      }
     231      setenv ("FONTCONFIG_SYSROOT", sysroot, 1);
     232      fprintf (stderr, "D: Creating %s\n", sysroot);
     233      mkdir_p (sysroot);
     234      retval++;
     235      d = FcStrBuildFilename ((const FcChar8 *) sysroot, basedir, NULL);
     236      fprintf (stderr, "D: Creating %s\n", d);
     237      mkdir_p ((const char *) d);
     238      free (d);
     239      retval++;
     240      free (dd);
     241      len = strlen ((const char *) doc) + strlen (basedir) + 1;
     242      dd = malloc (len);
     243      snprintf ((char *) dd, len, (char *) doc, basedir);
     244      if (!FcConfigParseAndLoadFromMemory (cfg, dd, FcFalse))
     245      {
     246  	fprintf (stderr, "%s: Unable to load a config\n", basedir);
     247  	goto bail;
     248      }
     249      sleep (1);
     250      c = FcDirCacheRead ((const FcChar8 *) basedir, FcFalse, cfg);
     251      FcDirCacheUnload (c);
     252      sleep (1);
     253      retval++;
     254      if (!FcConfigUptoDate (cfg))
     255      {
     256  	fprintf (stderr, "updated. need to reload (sysroot)\n");
     257  	goto bail;
     258      }
     259      retval = 0;
     260  bail:
     261      fprintf (stderr, "Cleaning up\n");
     262      if (basedir)
     263  	unlink_dirs (basedir);
     264      if (sysroot)
     265  	unlink_dirs (sysroot);
     266      if (dd)
     267  	free (dd);
     268      FcConfigDestroy (cfg);
     269  
     270      return retval;
     271  }