Home | History | Annotate | Download | only in cups
      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