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