]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/tempfile.c
cupsGetPPD* still used the old TMPDIR code.
[thirdparty/cups.git] / cups / tempfile.c
CommitLineData
ef416fc2 1/*
07623986 2 * Temp file utilities for CUPS.
ef416fc2 3 *
0bb02bfa
MS
4 * Copyright © 2007-2018 by Apple Inc.
5 * Copyright © 1997-2006 by Easy Software Products.
ef416fc2 6 *
0bb02bfa
MS
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more
8 * information.
ef416fc2 9 */
10
11/*
12 * Include necessary headers...
13 */
14
71e16022 15#include "cups-private.h"
ef416fc2 16#include <stdlib.h>
ef416fc2 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/*
2abf387c 27 * 'cupsTempFd()' - Creates a temporary file.
ef416fc2 28 *
2abf387c 29 * The temporary filename is returned in the filename buffer.
30 * The temporary file is opened for reading and writing.
ef416fc2 31 */
32
2abf387c 33int /* O - New file descriptor or -1 on error */
ef416fc2 34cupsTempFd(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 */
0bb02bfa
MS
40#if defined(__APPLE__) || defined(WIN32)
41 char tmppath[1024]; /* Temporary directory */
42#endif /* __APPLE__ || WIN32 */
ef416fc2 43#ifdef WIN32
ef416fc2 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 }
0bb02bfa
MS
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
9b440f8a
MS
65 * function should be called to get the proper per-user, per-process TMPDIR
66 * value. Currently this only happens if TMPDIR is not set or is set to
818bbe7a 67 * "/Users/...".
0bb02bfa
MS
68 */
69
818bbe7a 70 if ((tmpdir = getenv("TMPDIR")) != NULL && !strncmp(tmpdir, "/Users/", 7))
9b440f8a 71 tmpdir = NULL;
0bb02bfa 72
9b440f8a 73 if (!tmpdir)
0bb02bfa
MS
74 {
75 if (confstr(_CS_DARWIN_USER_TEMP_DIR, tmppath, sizeof(tmppath)))
76 tmpdir = tmppath;
77 else
78 tmpdir = "/private/tmp"; /* This should never happen */
79 }
80
ef416fc2 81#else
09a101d6 82 /*
83 * Previously we put root temporary files in the default CUPS temporary
84 * directory under /var/spool/cups. However, since the scheduler cleans
85 * out temporary files there and runs independently of the user apps, we
86 * don't want to use it unless specifically told to by cupsd.
87 */
ef416fc2 88
09a101d6 89 if ((tmpdir = getenv("TMPDIR")) == NULL)
09a101d6 90 tmpdir = "/tmp";
ef416fc2 91#endif /* WIN32 */
92
93 /*
94 * Make the temporary name using the specified directory...
95 */
96
97 tries = 0;
98
99 do
100 {
101#ifdef WIN32
102 /*
103 * Get the current time of day...
104 */
105
106 curtime = GetTickCount() + tries;
107
108 /*
109 * Format a string using the hex time values...
110 */
111
07623986 112 snprintf(filename, (size_t)len - 1, "%s/%05lx%08lx", tmpdir, GetCurrentProcessId(), curtime);
ef416fc2 113#else
114 /*
115 * Get the current time of day...
116 */
117
118 gettimeofday(&curtime, NULL);
119
120 /*
121 * Format a string using the hex time values...
122 */
123
07623986 124 snprintf(filename, (size_t)len - 1, "%s/%05x%08x", tmpdir, (unsigned)getpid(), (unsigned)(curtime.tv_sec + curtime.tv_usec + tries));
ef416fc2 125#endif /* WIN32 */
126
127 /*
128 * Open the file in "exclusive" mode, making sure that we don't
129 * stomp on an existing file or someone's symlink crack...
130 */
131
132#ifdef WIN32
133 fd = open(filename, _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY,
134 _S_IREAD | _S_IWRITE);
135#elif defined(O_NOFOLLOW)
136 fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
137#else
138 fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
139#endif /* WIN32 */
140
141 if (fd < 0 && errno != EEXIST)
142 break;
143
144 tries ++;
145 }
146 while (fd < 0 && tries < 1000);
147
148 /*
149 * Return the file descriptor...
150 */
151
152 return (fd);
153}
154
155
156/*
2abf387c 157 * 'cupsTempFile()' - Generates a temporary filename.
ef416fc2 158 *
2abf387c 159 * The temporary filename is returned in the filename buffer.
240214ef
MS
160 * This function is deprecated and will no longer generate a temporary
161 * filename - use @link cupsTempFd@ or @link cupsTempFile2@ instead.
ef416fc2 162 *
163 * @deprecated@
164 */
165
568fa3fa 166char * /* O - Filename or @code NULL@ on error */
ef416fc2 167cupsTempFile(char *filename, /* I - Pointer to buffer */
168 int len) /* I - Size of buffer */
169{
240214ef 170 (void)len;
ef416fc2 171
240214ef
MS
172 if (filename)
173 *filename = '\0';
ef416fc2 174
240214ef 175 return (NULL);
ef416fc2 176}
177
178
179/*
2abf387c 180 * 'cupsTempFile2()' - Creates a temporary CUPS file.
ef416fc2 181 *
2abf387c 182 * The temporary filename is returned in the filename buffer.
183 * The temporary file is opened for writing.
ef416fc2 184 *
8072030b 185 * @since CUPS 1.2/macOS 10.5@
ef416fc2 186 */
187
568fa3fa 188cups_file_t * /* O - CUPS file or @code NULL@ on error */
ef416fc2 189cupsTempFile2(char *filename, /* I - Pointer to buffer */
190 int len) /* I - Size of buffer */
191{
192 cups_file_t *file; /* CUPS file */
193 int fd; /* File descriptor */
194
195
196 if ((fd = cupsTempFd(filename, len)) < 0)
197 return (NULL);
198 else if ((file = cupsFileOpenFd(fd, "w")) == NULL)
199 {
200 close(fd);
201 unlink(filename);
202 return (NULL);
203 }
204 else
205 return (file);
206}