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