]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/tempfile.c
Migrate Windows conditional code to _WIN32 define.
[thirdparty/cups.git] / cups / tempfile.c
1 /*
2 * Temp file utilities for CUPS.
3 *
4 * Copyright © 2007-2018 by Apple Inc.
5 * Copyright © 1997-2006 by Easy Software Products.
6 *
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more
8 * information.
9 */
10
11 /*
12 * Include necessary headers...
13 */
14
15 #include "cups-private.h"
16 #include <stdlib.h>
17 #include <fcntl.h>
18 #include <sys/stat.h>
19 #if defined(_WIN32) || defined(__EMX__)
20 # include <io.h>
21 #else
22 # include <unistd.h>
23 #endif /* _WIN32 || __EMX__ */
24
25
26 /*
27 * 'cupsTempFd()' - Creates a temporary file.
28 *
29 * The temporary filename is returned in the filename buffer.
30 * The temporary file is opened for reading and writing.
31 */
32
33 int /* O - New file descriptor or -1 on error */
34 cupsTempFd(char *filename, /* I - Pointer to buffer */
35 int len) /* I - Size of buffer */
36 {
37 int fd; /* File descriptor for temp file */
38 int tries; /* Number of tries */
39 const char *tmpdir; /* TMPDIR environment var */
40 #if defined(__APPLE__) || defined(_WIN32)
41 char tmppath[1024]; /* Temporary directory */
42 #endif /* __APPLE__ || _WIN32 */
43 #ifdef _WIN32
44 DWORD curtime; /* Current time */
45 #else
46 struct timeval curtime; /* Current time */
47 #endif /* _WIN32 */
48
49
50 /*
51 * See if TMPDIR is defined...
52 */
53
54 #ifdef _WIN32
55 if ((tmpdir = getenv("TEMP")) == NULL)
56 {
57 GetTempPath(sizeof(tmppath), tmppath);
58 tmpdir = tmppath;
59 }
60
61 #elif defined(__APPLE__)
62 /*
63 * On macOS and iOS, the TMPDIR environment variable is not always the best
64 * location to place temporary files due to sandboxing. Instead, the confstr
65 * function should be called to get the proper per-user, per-process TMPDIR
66 * value.
67 */
68
69 if ((tmpdir = getenv("TMPDIR")) != NULL && access(tmpdir, W_OK))
70 tmpdir = NULL;
71
72 if (!tmpdir)
73 {
74 if (confstr(_CS_DARWIN_USER_TEMP_DIR, tmppath, sizeof(tmppath)))
75 tmpdir = tmppath;
76 else
77 tmpdir = "/private/tmp"; /* This should never happen */
78 }
79
80 #else
81 /*
82 * Previously we put root temporary files in the default CUPS temporary
83 * directory under /var/spool/cups. However, since the scheduler cleans
84 * out temporary files there and runs independently of the user apps, we
85 * don't want to use it unless specifically told to by cupsd.
86 */
87
88 if ((tmpdir = getenv("TMPDIR")) == NULL)
89 tmpdir = "/tmp";
90 #endif /* _WIN32 */
91
92 /*
93 * Make the temporary name using the specified directory...
94 */
95
96 tries = 0;
97
98 do
99 {
100 #ifdef _WIN32
101 /*
102 * Get the current time of day...
103 */
104
105 curtime = GetTickCount() + tries;
106
107 /*
108 * Format a string using the hex time values...
109 */
110
111 snprintf(filename, (size_t)len - 1, "%s/%05lx%08lx", tmpdir, GetCurrentProcessId(), curtime);
112 #else
113 /*
114 * Get the current time of day...
115 */
116
117 gettimeofday(&curtime, NULL);
118
119 /*
120 * Format a string using the hex time values...
121 */
122
123 snprintf(filename, (size_t)len - 1, "%s/%05x%08x", tmpdir, (unsigned)getpid(), (unsigned)(curtime.tv_sec + curtime.tv_usec + tries));
124 #endif /* _WIN32 */
125
126 /*
127 * Open the file in "exclusive" mode, making sure that we don't
128 * stomp on an existing file or someone's symlink crack...
129 */
130
131 #ifdef _WIN32
132 fd = open(filename, _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY,
133 _S_IREAD | _S_IWRITE);
134 #elif defined(O_NOFOLLOW)
135 fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
136 #else
137 fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
138 #endif /* _WIN32 */
139
140 if (fd < 0 && errno != EEXIST)
141 break;
142
143 tries ++;
144 }
145 while (fd < 0 && tries < 1000);
146
147 /*
148 * Return the file descriptor...
149 */
150
151 return (fd);
152 }
153
154
155 /*
156 * 'cupsTempFile()' - Generates a temporary filename.
157 *
158 * The temporary filename is returned in the filename buffer.
159 * This function is deprecated and will no longer generate a temporary
160 * filename - use @link cupsTempFd@ or @link cupsTempFile2@ instead.
161 *
162 * @deprecated@
163 */
164
165 char * /* O - Filename or @code NULL@ on error */
166 cupsTempFile(char *filename, /* I - Pointer to buffer */
167 int len) /* I - Size of buffer */
168 {
169 (void)len;
170
171 if (filename)
172 *filename = '\0';
173
174 return (NULL);
175 }
176
177
178 /*
179 * 'cupsTempFile2()' - Creates a temporary CUPS file.
180 *
181 * The temporary filename is returned in the filename buffer.
182 * The temporary file is opened for writing.
183 *
184 * @since CUPS 1.2/macOS 10.5@
185 */
186
187 cups_file_t * /* O - CUPS file or @code NULL@ on error */
188 cupsTempFile2(char *filename, /* I - Pointer to buffer */
189 int len) /* I - Size of buffer */
190 {
191 cups_file_t *file; /* CUPS file */
192 int fd; /* File descriptor */
193
194
195 if ((fd = cupsTempFd(filename, len)) < 0)
196 return (NULL);
197 else if ((file = cupsFileOpenFd(fd, "w")) == NULL)
198 {
199 close(fd);
200 unlink(filename);
201 return (NULL);
202 }
203 else
204 return (file);
205 }