(root)/
fontconfig-2.14.2/
test/
test-migration.c
       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 <sys/types.h>
      32  #include <dirent.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 HAVE_MKDTEMP
      43  #define fc_mkdtemp	mkdtemp
      44  #else
      45  char *
      46  fc_mkdtemp (char *template)
      47  {
      48      if (!mktemp (template) || mkdir (template, 0700))
      49  	return NULL;
      50  
      51      return template;
      52  }
      53  #endif
      54  
      55  FcBool
      56  mkdir_p(const char *dir)
      57  {
      58      char *parent;
      59      FcBool ret;
      60  
      61      if (strlen (dir) == 0)
      62  	return FcFalse;
      63      parent = (char *) FcStrDirname ((const FcChar8 *)dir);
      64      if (!parent)
      65  	return FcFalse;
      66      if (access (parent, F_OK) == 0)
      67  	ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0;
      68      else if (access (parent, F_OK) == -1)
      69  	ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0;
      70      else
      71  	ret = FcFalse;
      72      free (parent);
      73  
      74      return ret;
      75  }
      76  
      77  FcBool
      78  unlink_dirs(const char *dir)
      79  {
      80      DIR *d = opendir (dir);
      81      struct dirent *e;
      82      size_t len = strlen (dir);
      83      char *n = NULL;
      84      FcBool ret = FcTrue;
      85  #ifndef HAVE_STRUCT_DIRENT_D_TYPE
      86      struct stat statb;
      87  #endif
      88  
      89      if (!d)
      90  	return FcFalse;
      91      while ((e = readdir(d)) != NULL)
      92      {
      93  	size_t l;
      94  
      95  	if (strcmp (e->d_name, ".") == 0 ||
      96  	    strcmp (e->d_name, "..") == 0)
      97  	    continue;
      98  	l = strlen (e->d_name) + 1;
      99  	if (n)
     100  	    free (n);
     101  	n = malloc (l + len + 1);
     102  	strcpy (n, dir);
     103  	n[len] = '/';
     104  	strcpy (&n[len + 1], e->d_name);
     105  #ifdef HAVE_STRUCT_DIRENT_D_TYPE
     106  	if (e->d_type == DT_DIR)
     107  #else
     108  	if (stat (n, &statb) == -1)
     109  	{
     110  		fprintf (stderr, "E: %s\n", n);
     111  		ret = FcFalse;
     112  		break;
     113  	}
     114  	if (S_ISDIR (statb.st_mode))
     115  #endif
     116  	{
     117  	    if (!unlink_dirs (n))
     118  	    {
     119  		fprintf (stderr, "E: %s\n", n);
     120  		ret = FcFalse;
     121  		break;
     122  	    }
     123  	}
     124  	else
     125  	{
     126  	    if (unlink (n) == -1)
     127  	    {
     128  		fprintf (stderr, "E: %s\n", n);
     129  		ret = FcFalse;
     130  		break;
     131  	    }
     132  	}
     133      }
     134      if (n)
     135  	free (n);
     136      closedir (d);
     137  
     138      if (rmdir (dir) == -1)
     139      {
     140  	fprintf (stderr, "E: %s\n", dir);
     141  	return FcFalse;
     142      }
     143  
     144      return ret;
     145  }
     146  
     147  int
     148  main(void)
     149  {
     150      char template[32] = "fontconfig-XXXXXXXX";
     151      char *tmp = fc_mkdtemp (template);
     152      size_t len = strlen (tmp), xlen, dlen;
     153      char xdg[256], confd[256], fn[256], nfn[256], ud[256], nud[256];
     154      int ret = -1;
     155      FILE *fp;
     156      char *content = "<fontconfig></fontconfig>";
     157  
     158      strcpy (xdg, tmp);
     159      strcpy (&xdg[len], "/.config");
     160      setenv ("HOME", tmp, 1);
     161      setenv ("XDG_CONFIG_HOME", xdg, 1);
     162      xlen = strlen (xdg);
     163      strcpy (confd, xdg);
     164      strcpy (&confd[xlen], "/fontconfig");
     165      dlen = strlen (confd);
     166      /* In case there are no configuration files nor directory */
     167      FcInit ();
     168      if (access (confd, F_OK) == 0)
     169      {
     170  	fprintf (stderr, "%s unexpectedly exists\n", confd);
     171  	goto bail;
     172      }
     173      FcFini ();
     174      if (!unlink_dirs (tmp))
     175      {
     176  	fprintf (stderr, "Unable to clean up\n");
     177  	goto bail;
     178      }
     179      /* In case there are the user configuration file */
     180      strcpy (fn, tmp);
     181      strcpy (&fn[len], "/.fonts.conf");
     182      strcpy (nfn, confd);
     183      strcpy (&nfn[dlen], "/fonts.conf");
     184      if (!mkdir_p (confd))
     185      {
     186  	fprintf (stderr, "Unable to create a config dir: %s\n", confd);
     187  	goto bail;
     188      }
     189      if ((fp = fopen (fn, "wb")) == NULL)
     190      {
     191  	fprintf (stderr, "Unable to create a config file: %s\n", fn);
     192  	goto bail;
     193      }
     194      fwrite (content, sizeof (char), strlen (content), fp);
     195      fclose (fp);
     196      FcInit ();
     197      if (access (nfn, F_OK) != 0)
     198      {
     199  	fprintf (stderr, "migration failed for %s\n", nfn);
     200  	goto bail;
     201      }
     202      FcFini ();
     203      if (!unlink_dirs (tmp))
     204      {
     205  	fprintf (stderr, "Unable to clean up\n");
     206  	goto bail;
     207      }
     208      /* In case there are the user configuration dir */
     209      strcpy (ud, tmp);
     210      strcpy (&ud[len], "/.fonts.conf.d");
     211      strcpy (nud, confd);
     212      strcpy (&nud[dlen], "/conf.d");
     213      if (!mkdir_p (ud))
     214      {
     215  	fprintf (stderr, "Unable to create a config dir: %s\n", ud);
     216  	goto bail;
     217      }
     218      FcInit ();
     219      if (access (nud, F_OK) != 0)
     220      {
     221  	fprintf (stderr, "migration failed for %s\n", nud);
     222  	goto bail;
     223      }
     224      FcFini ();
     225  
     226      ret = 0;
     227  bail:
     228      unlink_dirs (tmp);
     229  
     230      return ret;
     231  }