test-migration.c revision 6fc018e4
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <sys/types.h>
6#include <dirent.h>
7#include <fontconfig/fontconfig.h>
8
9FcBool
10mkdir_p(const char *dir)
11{
12    char *parent;
13    FcBool ret;
14
15    if (strlen (dir) == 0)
16	return FcFalse;
17    parent = (char *) FcStrDirname (dir);
18    if (!parent)
19	return FcFalse;
20    if (access (parent, F_OK) == 0)
21	ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0;
22    else if (access (parent, F_OK) == -1)
23	ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0;
24    else
25	ret = FcFalse;
26    free (parent);
27
28    return ret;
29}
30
31FcBool
32unlink_dirs(const char *dir)
33{
34    DIR *d = opendir (dir);
35    struct dirent *e;
36    size_t len = strlen (dir);
37    char *n = NULL;
38    FcBool ret = FcTrue;
39
40    if (!d)
41	return FcFalse;
42    while ((e = readdir(d)) != NULL)
43    {
44	size_t l;
45
46	if (strcmp (e->d_name, ".") == 0 ||
47	    strcmp (e->d_name, "..") == 0)
48	    continue;
49	l = strlen (e->d_name) + 1;
50	if (n)
51	    free (n);
52	n = malloc (l + len + 1);
53	strcpy (n, dir);
54	n[len] = '/';
55	strcpy (&n[len + 1], e->d_name);
56	if (e->d_type == DT_DIR)
57	{
58	    if (!unlink_dirs (n))
59	    {
60		fprintf (stderr, "E: %s\n", n);
61		ret = FcFalse;
62		break;
63	    }
64	}
65	else
66	{
67	    if (unlink (n) == -1)
68	    {
69		fprintf (stderr, "E: %s\n", n);
70		ret = FcFalse;
71		break;
72	    }
73	}
74    }
75    if (n)
76	free (n);
77    closedir (d);
78
79    if (rmdir (dir) == -1)
80    {
81	fprintf (stderr, "E: %s\n", dir);
82	return FcFalse;
83    }
84
85    return ret;
86}
87
88int
89main(void)
90{
91    char template[32] = "fontconfig-XXXXXXXX";
92    char *tmp = mkdtemp (template);
93    size_t len = strlen (tmp), xlen, dlen;
94    char xdg[256], confd[256], fn[256], nfn[256], ud[256], nud[256];
95    int ret = -1;
96    FILE *fp;
97    char *content = "<fontconfig></fontconfig>";
98
99    strcpy (xdg, tmp);
100    strcpy (&xdg[len], "/.config");
101    setenv ("HOME", tmp, 1);
102    setenv ("XDG_CONFIG_HOME", xdg, 1);
103    xlen = strlen (xdg);
104    strcpy (confd, xdg);
105    strcpy (&confd[xlen], "/fontconfig");
106    dlen = strlen (confd);
107    /* In case there are no configuration files nor directory */
108    FcInit ();
109    if (access (confd, F_OK) == 0)
110    {
111	fprintf (stderr, "%s unexpectedly exists\n", confd);
112	goto bail;
113    }
114    FcFini ();
115    if (!unlink_dirs (tmp))
116    {
117	fprintf (stderr, "Unable to clean up\n");
118	goto bail;
119    }
120    /* In case there are the user configuration file */
121    strcpy (fn, tmp);
122    strcpy (&fn[len], "/.fonts.conf");
123    strcpy (nfn, confd);
124    strcpy (&nfn[dlen], "/fonts.conf");
125    if (!mkdir_p (confd))
126    {
127	fprintf (stderr, "Unable to create a config dir: %s\n", confd);
128	goto bail;
129    }
130    if ((fp = fopen (fn, "wb")) == NULL)
131    {
132	fprintf (stderr, "Unable to create a config file: %s\n", fn);
133	goto bail;
134    }
135    fwrite (content, sizeof (char), strlen (content), fp);
136    fclose (fp);
137    FcInit ();
138    if (access (nfn, F_OK) != 0)
139    {
140	fprintf (stderr, "migration failed for %s\n", nfn);
141	goto bail;
142    }
143    FcFini ();
144    if (!unlink_dirs (tmp))
145    {
146	fprintf (stderr, "Unable to clean up\n");
147	goto bail;
148    }
149    /* In case there are the user configuration dir */
150    strcpy (ud, tmp);
151    strcpy (&ud[len], "/.fonts.conf.d");
152    strcpy (nud, confd);
153    strcpy (&nud[dlen], "/conf.d");
154    if (!mkdir_p (ud))
155    {
156	fprintf (stderr, "Unable to create a config dir: %s\n", ud);
157	goto bail;
158    }
159    FcInit ();
160    if (access (nud, F_OK) != 0)
161    {
162	fprintf (stderr, "migration failed for %s\n", nud);
163	goto bail;
164    }
165    FcFini ();
166
167    ret = 0;
168bail:
169    unlink_dirs (tmp);
170
171    return ret;
172}
173