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