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