1/*
2 * "$Id: tempfile.c 11093 2013-07-03 20:48:42Z msweet $"
3 *
4 *   Temp file utilities for CUPS.
5 *
6 *   Copyright 2007-2012 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
46int					/* O - New file descriptor or -1 on error */
47cupsTempFd(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
162char *					/* O - Filename or @code NULL@ on error */
163cupsTempFile(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/OS X 10.5@
208 */
209
210cups_file_t *				/* O - CUPS file or @code NULL@ on error */
211cupsTempFile2(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 11093 2013-07-03 20:48:42Z msweet $".
233 */
234