1b09479dcSmrg/*
2b09479dcSmrg * fontconfig/test/test-migration.c
3b09479dcSmrg *
4b09479dcSmrg * Copyright © 2000 Keith Packard
5b09479dcSmrg * Copyright © 2013 Akira TAGOH
6b09479dcSmrg *
7b09479dcSmrg * Permission to use, copy, modify, distribute, and sell this software and its
8b09479dcSmrg * documentation for any purpose is hereby granted without fee, provided that
9b09479dcSmrg * the above copyright notice appear in all copies and that both that
10b09479dcSmrg * copyright notice and this permission notice appear in supporting
11b09479dcSmrg * documentation, and that the name of the author(s) not be used in
12b09479dcSmrg * advertising or publicity pertaining to distribution of the software without
13b09479dcSmrg * specific, written prior permission.  The authors make no
14b09479dcSmrg * representations about the suitability of this software for any purpose.  It
15b09479dcSmrg * is provided "as is" without express or implied warranty.
16b09479dcSmrg *
17b09479dcSmrg * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18b09479dcSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19b09479dcSmrg * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20b09479dcSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21b09479dcSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22b09479dcSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23b09479dcSmrg * PERFORMANCE OF THIS SOFTWARE.
24b09479dcSmrg */
25a32e9e42Smrg#ifdef HAVE_CONFIG_H
26a32e9e42Smrg#include "config.h"
27a32e9e42Smrg#endif
286fc018e4Smrg#include <stdio.h>
296fc018e4Smrg#include <stdlib.h>
306fc018e4Smrg#include <string.h>
316fc018e4Smrg#include <sys/types.h>
326fc018e4Smrg#include <dirent.h>
33a4e54154Smrg#ifdef HAVE_UNISTD_H
34a4e54154Smrg#include <unistd.h>
35a4e54154Smrg#endif
36b09479dcSmrg#ifndef HAVE_STRUCT_DIRENT_D_TYPE
37b09479dcSmrg#include <sys/types.h>
38b09479dcSmrg#include <sys/stat.h>
39b09479dcSmrg#endif
406fc018e4Smrg#include <fontconfig/fontconfig.h>
416fc018e4Smrg
42b09479dcSmrg#ifdef HAVE_MKDTEMP
43b09479dcSmrg#define fc_mkdtemp	mkdtemp
44b09479dcSmrg#else
45b09479dcSmrgchar *
46b09479dcSmrgfc_mkdtemp (char *template)
47b09479dcSmrg{
48b09479dcSmrg    if (!mktemp (template) || mkdir (template, 0700))
49b09479dcSmrg	return NULL;
50b09479dcSmrg
51b09479dcSmrg    return template;
52b09479dcSmrg}
53b09479dcSmrg#endif
54b09479dcSmrg
556fc018e4SmrgFcBool
566fc018e4Smrgmkdir_p(const char *dir)
576fc018e4Smrg{
586fc018e4Smrg    char *parent;
596fc018e4Smrg    FcBool ret;
606fc018e4Smrg
616fc018e4Smrg    if (strlen (dir) == 0)
626fc018e4Smrg	return FcFalse;
63953daebaSmrg    parent = (char *) FcStrDirname ((const FcChar8 *)dir);
646fc018e4Smrg    if (!parent)
656fc018e4Smrg	return FcFalse;
666fc018e4Smrg    if (access (parent, F_OK) == 0)
676fc018e4Smrg	ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0;
686fc018e4Smrg    else if (access (parent, F_OK) == -1)
696fc018e4Smrg	ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0;
706fc018e4Smrg    else
716fc018e4Smrg	ret = FcFalse;
726fc018e4Smrg    free (parent);
736fc018e4Smrg
746fc018e4Smrg    return ret;
756fc018e4Smrg}
766fc018e4Smrg
776fc018e4SmrgFcBool
786fc018e4Smrgunlink_dirs(const char *dir)
796fc018e4Smrg{
806fc018e4Smrg    DIR *d = opendir (dir);
816fc018e4Smrg    struct dirent *e;
826fc018e4Smrg    size_t len = strlen (dir);
836fc018e4Smrg    char *n = NULL;
846fc018e4Smrg    FcBool ret = FcTrue;
85b09479dcSmrg#ifndef HAVE_STRUCT_DIRENT_D_TYPE
86b09479dcSmrg    struct stat statb;
87b09479dcSmrg#endif
886fc018e4Smrg
896fc018e4Smrg    if (!d)
906fc018e4Smrg	return FcFalse;
916fc018e4Smrg    while ((e = readdir(d)) != NULL)
926fc018e4Smrg    {
936fc018e4Smrg	size_t l;
946fc018e4Smrg
956fc018e4Smrg	if (strcmp (e->d_name, ".") == 0 ||
966fc018e4Smrg	    strcmp (e->d_name, "..") == 0)
976fc018e4Smrg	    continue;
986fc018e4Smrg	l = strlen (e->d_name) + 1;
996fc018e4Smrg	if (n)
1006fc018e4Smrg	    free (n);
1016fc018e4Smrg	n = malloc (l + len + 1);
1026fc018e4Smrg	strcpy (n, dir);
1036fc018e4Smrg	n[len] = '/';
1046fc018e4Smrg	strcpy (&n[len + 1], e->d_name);
105b09479dcSmrg#ifdef HAVE_STRUCT_DIRENT_D_TYPE
1066fc018e4Smrg	if (e->d_type == DT_DIR)
107b09479dcSmrg#else
108b09479dcSmrg	if (stat (n, &statb) == -1)
109b09479dcSmrg	{
110b09479dcSmrg		fprintf (stderr, "E: %s\n", n);
111b09479dcSmrg		ret = FcFalse;
112b09479dcSmrg		break;
113b09479dcSmrg	}
114b09479dcSmrg	if (S_ISDIR (statb.st_mode))
115b09479dcSmrg#endif
1166fc018e4Smrg	{
1176fc018e4Smrg	    if (!unlink_dirs (n))
1186fc018e4Smrg	    {
1196fc018e4Smrg		fprintf (stderr, "E: %s\n", n);
1206fc018e4Smrg		ret = FcFalse;
1216fc018e4Smrg		break;
1226fc018e4Smrg	    }
1236fc018e4Smrg	}
1246fc018e4Smrg	else
1256fc018e4Smrg	{
1266fc018e4Smrg	    if (unlink (n) == -1)
1276fc018e4Smrg	    {
1286fc018e4Smrg		fprintf (stderr, "E: %s\n", n);
1296fc018e4Smrg		ret = FcFalse;
1306fc018e4Smrg		break;
1316fc018e4Smrg	    }
1326fc018e4Smrg	}
1336fc018e4Smrg    }
1346fc018e4Smrg    if (n)
1356fc018e4Smrg	free (n);
1366fc018e4Smrg    closedir (d);
1376fc018e4Smrg
1386fc018e4Smrg    if (rmdir (dir) == -1)
1396fc018e4Smrg    {
1406fc018e4Smrg	fprintf (stderr, "E: %s\n", dir);
1416fc018e4Smrg	return FcFalse;
1426fc018e4Smrg    }
1436fc018e4Smrg
1446fc018e4Smrg    return ret;
1456fc018e4Smrg}
1466fc018e4Smrg
1476fc018e4Smrgint
1486fc018e4Smrgmain(void)
1496fc018e4Smrg{
1506fc018e4Smrg    char template[32] = "fontconfig-XXXXXXXX";
151b09479dcSmrg    char *tmp = fc_mkdtemp (template);
1526fc018e4Smrg    size_t len = strlen (tmp), xlen, dlen;
1536fc018e4Smrg    char xdg[256], confd[256], fn[256], nfn[256], ud[256], nud[256];
1546fc018e4Smrg    int ret = -1;
1556fc018e4Smrg    FILE *fp;
1566fc018e4Smrg    char *content = "<fontconfig></fontconfig>";
1576fc018e4Smrg
1586fc018e4Smrg    strcpy (xdg, tmp);
1596fc018e4Smrg    strcpy (&xdg[len], "/.config");
1606fc018e4Smrg    setenv ("HOME", tmp, 1);
1616fc018e4Smrg    setenv ("XDG_CONFIG_HOME", xdg, 1);
1626fc018e4Smrg    xlen = strlen (xdg);
1636fc018e4Smrg    strcpy (confd, xdg);
1646fc018e4Smrg    strcpy (&confd[xlen], "/fontconfig");
1656fc018e4Smrg    dlen = strlen (confd);
1666fc018e4Smrg    /* In case there are no configuration files nor directory */
1676fc018e4Smrg    FcInit ();
1686fc018e4Smrg    if (access (confd, F_OK) == 0)
1696fc018e4Smrg    {
1706fc018e4Smrg	fprintf (stderr, "%s unexpectedly exists\n", confd);
1716fc018e4Smrg	goto bail;
1726fc018e4Smrg    }
1736fc018e4Smrg    FcFini ();
1746fc018e4Smrg    if (!unlink_dirs (tmp))
1756fc018e4Smrg    {
1766fc018e4Smrg	fprintf (stderr, "Unable to clean up\n");
1776fc018e4Smrg	goto bail;
1786fc018e4Smrg    }
1796fc018e4Smrg    /* In case there are the user configuration file */
1806fc018e4Smrg    strcpy (fn, tmp);
1816fc018e4Smrg    strcpy (&fn[len], "/.fonts.conf");
1826fc018e4Smrg    strcpy (nfn, confd);
1836fc018e4Smrg    strcpy (&nfn[dlen], "/fonts.conf");
1846fc018e4Smrg    if (!mkdir_p (confd))
1856fc018e4Smrg    {
1866fc018e4Smrg	fprintf (stderr, "Unable to create a config dir: %s\n", confd);
1876fc018e4Smrg	goto bail;
1886fc018e4Smrg    }
1896fc018e4Smrg    if ((fp = fopen (fn, "wb")) == NULL)
1906fc018e4Smrg    {
1916fc018e4Smrg	fprintf (stderr, "Unable to create a config file: %s\n", fn);
1926fc018e4Smrg	goto bail;
1936fc018e4Smrg    }
1946fc018e4Smrg    fwrite (content, sizeof (char), strlen (content), fp);
1956fc018e4Smrg    fclose (fp);
1966fc018e4Smrg    FcInit ();
1976fc018e4Smrg    if (access (nfn, F_OK) != 0)
1986fc018e4Smrg    {
1996fc018e4Smrg	fprintf (stderr, "migration failed for %s\n", nfn);
2006fc018e4Smrg	goto bail;
2016fc018e4Smrg    }
2026fc018e4Smrg    FcFini ();
2036fc018e4Smrg    if (!unlink_dirs (tmp))
2046fc018e4Smrg    {
2056fc018e4Smrg	fprintf (stderr, "Unable to clean up\n");
2066fc018e4Smrg	goto bail;
2076fc018e4Smrg    }
2086fc018e4Smrg    /* In case there are the user configuration dir */
2096fc018e4Smrg    strcpy (ud, tmp);
2106fc018e4Smrg    strcpy (&ud[len], "/.fonts.conf.d");
2116fc018e4Smrg    strcpy (nud, confd);
2126fc018e4Smrg    strcpy (&nud[dlen], "/conf.d");
2136fc018e4Smrg    if (!mkdir_p (ud))
2146fc018e4Smrg    {
2156fc018e4Smrg	fprintf (stderr, "Unable to create a config dir: %s\n", ud);
2166fc018e4Smrg	goto bail;
2176fc018e4Smrg    }
2186fc018e4Smrg    FcInit ();
2196fc018e4Smrg    if (access (nud, F_OK) != 0)
2206fc018e4Smrg    {
2216fc018e4Smrg	fprintf (stderr, "migration failed for %s\n", nud);
2226fc018e4Smrg	goto bail;
2236fc018e4Smrg    }
2246fc018e4Smrg    FcFini ();
2256fc018e4Smrg
2266fc018e4Smrg    ret = 0;
2276fc018e4Smrgbail:
2286fc018e4Smrg    unlink_dirs (tmp);
2296fc018e4Smrg
2306fc018e4Smrg    return ret;
2316fc018e4Smrg}
232