test-migration.c revision 953daeba
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 */
256fc018e4Smrg#include <stdio.h>
266fc018e4Smrg#include <stdlib.h>
276fc018e4Smrg#include <string.h>
286fc018e4Smrg#include <unistd.h>
296fc018e4Smrg#include <sys/types.h>
306fc018e4Smrg#include <dirent.h>
31b09479dcSmrg#ifndef HAVE_STRUCT_DIRENT_D_TYPE
32b09479dcSmrg#include <sys/types.h>
33b09479dcSmrg#include <sys/stat.h>
34b09479dcSmrg#include <unistd.h>
35b09479dcSmrg#endif
366fc018e4Smrg#include <fontconfig/fontconfig.h>
376fc018e4Smrg
38b09479dcSmrg#ifdef HAVE_MKDTEMP
39b09479dcSmrg#define fc_mkdtemp	mkdtemp
40b09479dcSmrg#else
41b09479dcSmrgchar *
42b09479dcSmrgfc_mkdtemp (char *template)
43b09479dcSmrg{
44b09479dcSmrg    if (!mktemp (template) || mkdir (template, 0700))
45b09479dcSmrg	return NULL;
46b09479dcSmrg
47b09479dcSmrg    return template;
48b09479dcSmrg}
49b09479dcSmrg#endif
50b09479dcSmrg
516fc018e4SmrgFcBool
526fc018e4Smrgmkdir_p(const char *dir)
536fc018e4Smrg{
546fc018e4Smrg    char *parent;
556fc018e4Smrg    FcBool ret;
566fc018e4Smrg
576fc018e4Smrg    if (strlen (dir) == 0)
586fc018e4Smrg	return FcFalse;
59953daebaSmrg    parent = (char *) FcStrDirname ((const FcChar8 *)dir);
606fc018e4Smrg    if (!parent)
616fc018e4Smrg	return FcFalse;
626fc018e4Smrg    if (access (parent, F_OK) == 0)
636fc018e4Smrg	ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0;
646fc018e4Smrg    else if (access (parent, F_OK) == -1)
656fc018e4Smrg	ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0;
666fc018e4Smrg    else
676fc018e4Smrg	ret = FcFalse;
686fc018e4Smrg    free (parent);
696fc018e4Smrg
706fc018e4Smrg    return ret;
716fc018e4Smrg}
726fc018e4Smrg
736fc018e4SmrgFcBool
746fc018e4Smrgunlink_dirs(const char *dir)
756fc018e4Smrg{
766fc018e4Smrg    DIR *d = opendir (dir);
776fc018e4Smrg    struct dirent *e;
786fc018e4Smrg    size_t len = strlen (dir);
796fc018e4Smrg    char *n = NULL;
806fc018e4Smrg    FcBool ret = FcTrue;
81b09479dcSmrg#ifndef HAVE_STRUCT_DIRENT_D_TYPE
82b09479dcSmrg    struct stat statb;
83b09479dcSmrg#endif
846fc018e4Smrg
856fc018e4Smrg    if (!d)
866fc018e4Smrg	return FcFalse;
876fc018e4Smrg    while ((e = readdir(d)) != NULL)
886fc018e4Smrg    {
896fc018e4Smrg	size_t l;
906fc018e4Smrg
916fc018e4Smrg	if (strcmp (e->d_name, ".") == 0 ||
926fc018e4Smrg	    strcmp (e->d_name, "..") == 0)
936fc018e4Smrg	    continue;
946fc018e4Smrg	l = strlen (e->d_name) + 1;
956fc018e4Smrg	if (n)
966fc018e4Smrg	    free (n);
976fc018e4Smrg	n = malloc (l + len + 1);
986fc018e4Smrg	strcpy (n, dir);
996fc018e4Smrg	n[len] = '/';
1006fc018e4Smrg	strcpy (&n[len + 1], e->d_name);
101b09479dcSmrg#ifdef HAVE_STRUCT_DIRENT_D_TYPE
1026fc018e4Smrg	if (e->d_type == DT_DIR)
103b09479dcSmrg#else
104b09479dcSmrg	if (stat (n, &statb) == -1)
105b09479dcSmrg	{
106b09479dcSmrg		fprintf (stderr, "E: %s\n", n);
107b09479dcSmrg		ret = FcFalse;
108b09479dcSmrg		break;
109b09479dcSmrg	}
110b09479dcSmrg	if (S_ISDIR (statb.st_mode))
111b09479dcSmrg#endif
1126fc018e4Smrg	{
1136fc018e4Smrg	    if (!unlink_dirs (n))
1146fc018e4Smrg	    {
1156fc018e4Smrg		fprintf (stderr, "E: %s\n", n);
1166fc018e4Smrg		ret = FcFalse;
1176fc018e4Smrg		break;
1186fc018e4Smrg	    }
1196fc018e4Smrg	}
1206fc018e4Smrg	else
1216fc018e4Smrg	{
1226fc018e4Smrg	    if (unlink (n) == -1)
1236fc018e4Smrg	    {
1246fc018e4Smrg		fprintf (stderr, "E: %s\n", n);
1256fc018e4Smrg		ret = FcFalse;
1266fc018e4Smrg		break;
1276fc018e4Smrg	    }
1286fc018e4Smrg	}
1296fc018e4Smrg    }
1306fc018e4Smrg    if (n)
1316fc018e4Smrg	free (n);
1326fc018e4Smrg    closedir (d);
1336fc018e4Smrg
1346fc018e4Smrg    if (rmdir (dir) == -1)
1356fc018e4Smrg    {
1366fc018e4Smrg	fprintf (stderr, "E: %s\n", dir);
1376fc018e4Smrg	return FcFalse;
1386fc018e4Smrg    }
1396fc018e4Smrg
1406fc018e4Smrg    return ret;
1416fc018e4Smrg}
1426fc018e4Smrg
1436fc018e4Smrgint
1446fc018e4Smrgmain(void)
1456fc018e4Smrg{
1466fc018e4Smrg    char template[32] = "fontconfig-XXXXXXXX";
147b09479dcSmrg    char *tmp = fc_mkdtemp (template);
1486fc018e4Smrg    size_t len = strlen (tmp), xlen, dlen;
1496fc018e4Smrg    char xdg[256], confd[256], fn[256], nfn[256], ud[256], nud[256];
1506fc018e4Smrg    int ret = -1;
1516fc018e4Smrg    FILE *fp;
1526fc018e4Smrg    char *content = "<fontconfig></fontconfig>";
1536fc018e4Smrg
1546fc018e4Smrg    strcpy (xdg, tmp);
1556fc018e4Smrg    strcpy (&xdg[len], "/.config");
1566fc018e4Smrg    setenv ("HOME", tmp, 1);
1576fc018e4Smrg    setenv ("XDG_CONFIG_HOME", xdg, 1);
1586fc018e4Smrg    xlen = strlen (xdg);
1596fc018e4Smrg    strcpy (confd, xdg);
1606fc018e4Smrg    strcpy (&confd[xlen], "/fontconfig");
1616fc018e4Smrg    dlen = strlen (confd);
1626fc018e4Smrg    /* In case there are no configuration files nor directory */
1636fc018e4Smrg    FcInit ();
1646fc018e4Smrg    if (access (confd, F_OK) == 0)
1656fc018e4Smrg    {
1666fc018e4Smrg	fprintf (stderr, "%s unexpectedly exists\n", confd);
1676fc018e4Smrg	goto bail;
1686fc018e4Smrg    }
1696fc018e4Smrg    FcFini ();
1706fc018e4Smrg    if (!unlink_dirs (tmp))
1716fc018e4Smrg    {
1726fc018e4Smrg	fprintf (stderr, "Unable to clean up\n");
1736fc018e4Smrg	goto bail;
1746fc018e4Smrg    }
1756fc018e4Smrg    /* In case there are the user configuration file */
1766fc018e4Smrg    strcpy (fn, tmp);
1776fc018e4Smrg    strcpy (&fn[len], "/.fonts.conf");
1786fc018e4Smrg    strcpy (nfn, confd);
1796fc018e4Smrg    strcpy (&nfn[dlen], "/fonts.conf");
1806fc018e4Smrg    if (!mkdir_p (confd))
1816fc018e4Smrg    {
1826fc018e4Smrg	fprintf (stderr, "Unable to create a config dir: %s\n", confd);
1836fc018e4Smrg	goto bail;
1846fc018e4Smrg    }
1856fc018e4Smrg    if ((fp = fopen (fn, "wb")) == NULL)
1866fc018e4Smrg    {
1876fc018e4Smrg	fprintf (stderr, "Unable to create a config file: %s\n", fn);
1886fc018e4Smrg	goto bail;
1896fc018e4Smrg    }
1906fc018e4Smrg    fwrite (content, sizeof (char), strlen (content), fp);
1916fc018e4Smrg    fclose (fp);
1926fc018e4Smrg    FcInit ();
1936fc018e4Smrg    if (access (nfn, F_OK) != 0)
1946fc018e4Smrg    {
1956fc018e4Smrg	fprintf (stderr, "migration failed for %s\n", nfn);
1966fc018e4Smrg	goto bail;
1976fc018e4Smrg    }
1986fc018e4Smrg    FcFini ();
1996fc018e4Smrg    if (!unlink_dirs (tmp))
2006fc018e4Smrg    {
2016fc018e4Smrg	fprintf (stderr, "Unable to clean up\n");
2026fc018e4Smrg	goto bail;
2036fc018e4Smrg    }
2046fc018e4Smrg    /* In case there are the user configuration dir */
2056fc018e4Smrg    strcpy (ud, tmp);
2066fc018e4Smrg    strcpy (&ud[len], "/.fonts.conf.d");
2076fc018e4Smrg    strcpy (nud, confd);
2086fc018e4Smrg    strcpy (&nud[dlen], "/conf.d");
2096fc018e4Smrg    if (!mkdir_p (ud))
2106fc018e4Smrg    {
2116fc018e4Smrg	fprintf (stderr, "Unable to create a config dir: %s\n", ud);
2126fc018e4Smrg	goto bail;
2136fc018e4Smrg    }
2146fc018e4Smrg    FcInit ();
2156fc018e4Smrg    if (access (nud, F_OK) != 0)
2166fc018e4Smrg    {
2176fc018e4Smrg	fprintf (stderr, "migration failed for %s\n", nud);
2186fc018e4Smrg	goto bail;
2196fc018e4Smrg    }
2206fc018e4Smrg    FcFini ();
2216fc018e4Smrg
2226fc018e4Smrg    ret = 0;
2236fc018e4Smrgbail:
2246fc018e4Smrg    unlink_dirs (tmp);
2256fc018e4Smrg
2266fc018e4Smrg    return ret;
2276fc018e4Smrg}
228