warn deprecated only when migration failed
[platform/upstream/fontconfig.git] / src / fccompat.c
1 /*
2  * fontconfig/src/fccompat.c
3  *
4  * Copyright © 2012 Red Hat, Inc.
5  *
6  * Author(s):
7  *  Akira TAGOH
8  *
9  * Permission to use, copy, modify, distribute, and sell this software and its
10  * documentation for any purpose is hereby granted without fee, provided that
11  * the above copyright notice appear in all copies and that both that
12  * copyright notice and this permission notice appear in supporting
13  * documentation, and that the name of the author(s) not be used in
14  * advertising or publicity pertaining to distribution of the software without
15  * specific, written prior permission.  The authors make no
16  * representations about the suitability of this software for any purpose.  It
17  * is provided "as is" without express or implied warranty.
18  *
19  * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
20  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
21  * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
22  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
23  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
24  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
25  * PERFORMANCE OF THIS SOFTWARE.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "fcint.h"
33
34 #include <errno.h>
35 #if HAVE_SYS_TYPES_H
36 #include <sys/types.h>
37 #endif
38 #if HAVE_SYS_STAT_H
39 #include <sys/stat.h>
40 #endif
41 #if HAVE_FCNTL_H
42 #include <fcntl.h>
43 #endif
44 #include <stdarg.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <time.h>
48
49 #ifdef O_CLOEXEC
50 #define FC_O_CLOEXEC O_CLOEXEC
51 #else
52 #define FC_O_CLOEXEC 0
53 #endif
54 #ifdef O_LARGEFILE
55 #define FC_O_LARGEFILE O_LARGEFILE
56 #else
57 #define FC_O_LARGEFILE 0
58 #endif
59 #ifdef O_BINARY
60 #define FC_O_BINARY O_BINARY
61 #else
62 #define FC_O_BINARY 0
63 #endif
64 #ifdef O_TEMPORARY
65 #define FC_O_TEMPORARY O_TEMPORARY
66 #else
67 #define FC_O_TEMPORARY 0
68 #endif
69 #ifdef O_NOINHERIT
70 #define FC_O_NOINHERIT O_NOINHERIT
71 #else
72 #define FC_O_NOINHERIT 0
73 #endif
74
75 #if !defined (HAVE_MKOSTEMP) && !defined(HAVE_MKSTEMP) && !defined(HAVE__MKTEMP_S)
76 static int
77 mkstemp (char *template)
78 {
79     static const char s[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
80     int fd, i;
81     size_t l;
82
83     if (template == NULL)
84     {
85         errno = EINVAL;
86         return -1;
87     }
88     l = strlen (template);
89     if (l < 6 || strcmp (&template[l - 6], "XXXXXX") != 0)
90     {
91         errno = EINVAL;
92         return -1;
93     }
94     do
95     {
96         errno = 0;
97         for (i = l - 6; i < l; i++)
98         {
99             int r = FcRandom ();
100             template[i] = s[r % 62];
101         }
102         fd = FcOpen (template, FC_O_BINARY | O_CREAT | O_EXCL | FC_O_TEMPORARY | FC_O_NOINHERIT | O_RDWR, 0600);
103     } while (fd < 0 && errno == EEXIST);
104     if (fd >= 0)
105         errno = 0;
106
107     return fd;
108 }
109 #define HAVE_MKSTEMP 1
110 #endif
111
112 int
113 FcOpen(const char *pathname, int flags, ...)
114 {
115     int fd = -1;
116
117     if (flags & O_CREAT)
118     {
119         va_list ap;
120         mode_t mode;
121
122         va_start(ap, flags);
123         mode = (mode_t) va_arg(ap, int);
124         va_end(ap);
125
126         fd = open(pathname, flags | FC_O_CLOEXEC | FC_O_LARGEFILE, mode);
127     }
128     else
129     {
130         fd = open(pathname, flags | FC_O_CLOEXEC | FC_O_LARGEFILE);
131     }
132
133     return fd;
134 }
135
136 int
137 FcMakeTempfile (char *template)
138 {
139     int fd = -1;
140
141 #if HAVE_MKOSTEMP
142     fd = mkostemp (template, FC_O_CLOEXEC);
143 #elif HAVE_MKSTEMP
144     fd = mkstemp (template);
145 #  ifdef F_DUPFD_CLOEXEC
146     if (fd != -1)
147     {
148         int newfd = fcntl(fd, F_DUPFD_CLOEXEC, STDIN_FILENO);
149
150         close(fd);
151         fd = newfd;
152     }
153 #  elif defined(FD_CLOEXEC)
154     if (fd != -1)
155     {
156         fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
157     }
158 #  endif
159 #elif HAVE__MKTEMP_S
160    if (_mktemp_s(template, strlen(template) + 1) != 0)
161        return -1;
162    fd = FcOpen(template, O_RDWR | O_EXCL | O_CREAT, 0600);
163 #endif
164
165     return fd;
166 }
167
168 int32_t
169 FcRandom(void)
170 {
171     int32_t result;
172
173 #if HAVE_RANDOM_R
174     static struct random_data fcrandbuf;
175     static char statebuf[256];
176     static FcBool initialized = FcFalse;
177
178     if (initialized != FcTrue)
179     {
180         initstate_r(time(NULL), statebuf, 256, &fcrandbuf);
181         initialized = FcTrue;
182     }
183
184     random_r(&fcrandbuf, &result);
185 #elif HAVE_RANDOM
186     static char statebuf[256];
187     char *state;
188     static FcBool initialized = FcFalse;
189
190     if (initialized != FcTrue)
191     {
192         state = initstate(time(NULL), statebuf, 256);
193         initialized = FcTrue;
194     }
195     else
196         state = setstate(statebuf);
197
198     result = random();
199
200     setstate(state);
201 #elif HAVE_LRAND48
202     result = lrand48();
203 #elif HAVE_RAND_R
204     static unsigned int seed = time(NULL);
205
206     result = rand_r(&seed);
207 #elif HAVE_RAND
208     static FcBool initialized = FcFalse;
209
210     if (initialized != FcTrue)
211     {
212         srand(time(NULL));
213         initialized = FcTrue;
214     }
215     result = rand();
216 #else
217 # error no random number generator function available.
218 #endif
219
220     return result;
221 }
222
223 #ifdef _WIN32
224 #include <direct.h>
225 #define mkdir(path,mode) _mkdir(path)
226 #endif
227
228 FcBool
229 FcMakeDirectory (const FcChar8 *dir)
230 {
231     FcChar8 *parent;
232     FcBool  ret;
233
234     if (strlen ((char *) dir) == 0)
235         return FcFalse;
236
237     parent = FcStrDirname (dir);
238     if (!parent)
239         return FcFalse;
240     if (access ((char *) parent, F_OK) == 0)
241         ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0;
242     else if (access ((char *) parent, F_OK) == -1)
243         ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0;
244     else
245         ret = FcFalse;
246     FcStrFree (parent);
247     return ret;
248 }