Load cups into easysw/current.
[thirdparty/cups.git] / cups / tempfile.c
1 /*
2  * "$Id: tempfile.c 4918 2006-01-12 05:14:40Z mike $"
3  *
4  *   Temp file utilities for the Common UNIX Printing System (CUPS).
5  *
6  *   Copyright 1997-2005 by Easy Software Products.
7  *
8  *   These coded instructions, statements, and computer programs are the
9  *   property of Easy Software Products and are protected by Federal
10  *   copyright law.  Distribution and use rights are outlined in the file
11  *   "LICENSE.txt" which should have been included with this file.  If this
12  *   file is missing or damaged please contact Easy Software Products
13  *   at:
14  *
15  *       Attn: CUPS Licensing Information
16  *       Easy Software Products
17  *       44141 Airport View Drive, Suite 204
18  *       Hollywood, Maryland 20636 USA
19  *
20  *       Voice: (301) 373-9600
21  *       EMail: cups-info@cups.org
22  *         WWW: http://www.cups.org
23  *
24  *   This file is subject to the Apple OS-Developed Software exception.
25  *
26  * Contents:
27  *
28  *   cupsTempFd()    - Create a temporary file.
29  *   cupsTempFile()  - Generate a temporary filename.
30  *   cupsTempFile2() - Create a temporary CUPS file.
31  */
32
33 /*
34  * Include necessary headers...
35  */
36
37 #include "globals.h"
38 #include "debug.h"
39 #include <stdlib.h>
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <sys/stat.h>
43 #if defined(WIN32) || defined(__EMX__)
44 #  include <io.h>
45 #else
46 #  include <unistd.h>
47 #endif /* WIN32 || __EMX__ */
48
49
50 /*
51  * 'cupsTempFd()' - Create a temporary file.
52  *
53  * The temporary filename is stored in the filename buffer.
54  */
55
56 int                                     /* O - New file descriptor */
57 cupsTempFd(char *filename,              /* I - Pointer to buffer */
58            int  len)                    /* I - Size of buffer */
59 {
60   int           fd;                     /* File descriptor for temp file */
61   int           tries;                  /* Number of tries */
62   const char    *tmpdir;                /* TMPDIR environment var */
63 #ifdef WIN32
64   char          tmppath[1024];          /* Windows temporary directory */
65   DWORD         curtime;                /* Current time */
66 #else
67   struct timeval curtime;               /* Current time */
68 #endif /* WIN32 */
69
70
71  /*
72   * See if TMPDIR is defined...
73   */
74
75 #ifdef WIN32
76   if ((tmpdir = getenv("TEMP")) == NULL)
77   {
78     GetTempPath(sizeof(tmppath), tmppath);
79     tmpdir = tmppath;
80   }
81 #else
82   if ((tmpdir = getenv("TMPDIR")) == NULL)
83   {
84    /*
85     * Put root temp files in restricted temp directory...
86     */
87
88     if (getuid() == 0)
89       tmpdir = CUPS_REQUESTS "/tmp";
90     else
91       tmpdir = "/tmp";
92   }
93 #endif /* WIN32 */
94
95  /*
96   * Make the temporary name using the specified directory...
97   */
98
99   tries = 0;
100
101   do
102   {
103 #ifdef WIN32
104    /*
105     * Get the current time of day...
106     */
107
108     curtime =  GetTickCount() + tries;
109
110    /*
111     * Format a string using the hex time values...
112     */
113
114     snprintf(filename, len - 1, "%s/%05lx%08lx", tmpdir,
115              GetCurrentProcessId(), curtime);
116 #else
117    /*
118     * Get the current time of day...
119     */
120
121     gettimeofday(&curtime, NULL);
122
123    /*
124     * Format a string using the hex time values...
125     */
126
127     snprintf(filename, len - 1, "%s/%08lx%05lx", tmpdir,
128              (unsigned long)curtime.tv_sec, (unsigned long)curtime.tv_usec);
129 #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     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     if (fd < 0 && errno != EEXIST)
146       break;
147
148     tries ++;
149   }
150   while (fd < 0 && tries < 1000);
151
152  /*
153   * Return the file descriptor...
154   */
155
156   return (fd);
157 }
158
159
160 /*
161  * 'cupsTempFile()' - Generate a temporary filename.
162  *
163  * The temporary filename is stored in the filename buffer.
164  * This function is deprecated - use cupsTempFd() or cupsTempFile2()
165  * instead.
166  *
167  * @deprecated@
168  */
169
170 char *                                  /* O - Filename */
171 cupsTempFile(char *filename,            /* I - Pointer to buffer */
172              int  len)                  /* I - Size of buffer */
173 {
174   int           fd;                     /* File descriptor for temp file */
175   _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
176
177
178  /*
179   * See if a filename was specified...
180   */
181
182   if (filename == NULL)
183   {
184     filename = cg->tempfile;
185     len      = sizeof(cg->tempfile);
186   }
187
188  /*
189   * Create the temporary file...
190   */
191
192   if ((fd = cupsTempFd(filename, len)) < 0)
193     return (NULL);
194
195  /*
196   * Close the temp file - it'll be reopened later as needed...
197   */
198
199   close(fd);
200
201  /*
202   * Return the temp filename...
203   */
204
205   return (filename);
206 }
207
208
209 /*
210  * 'cupsTempFile2()' - Create a temporary CUPS file.
211  *
212  * The temporary filename is stored in the filename buffer.
213  *
214  * @since CUPS 1.2@
215  */
216
217 cups_file_t *                           /* O - CUPS file or NULL on error */
218 cupsTempFile2(char *filename,           /* I - Pointer to buffer */
219               int  len)                 /* I - Size of buffer */
220 {
221   cups_file_t   *file;                  /* CUPS file */
222   int           fd;                     /* File descriptor */
223
224
225   if ((fd = cupsTempFd(filename, len)) < 0)
226     return (NULL);
227   else if ((file = cupsFileOpenFd(fd, "w")) == NULL)
228   {
229     close(fd);
230     unlink(filename);
231     return (NULL);
232   }
233   else
234     return (file);
235 }
236
237
238 /*
239  * End of "$Id: tempfile.c 4918 2006-01-12 05:14:40Z mike $".
240  */