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