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