]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/tempfile.c
cupsTempFd() did not work in some situations (STR #3382)
[thirdparty/cups.git] / cups / tempfile.c
index 5afee2061a5858d880f8751fa80c9532529ec040..fc949b2a2481fe53bbb33a0781ac64c5a49af1c0 100644 (file)
@@ -1,43 +1,33 @@
 /*
- * "$Id: tempfile.c,v 1.4 2002/03/01 19:53:30 mike Exp $"
+ * "$Id$"
  *
  *   Temp file utilities for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 1997-2002 by Easy Software Products.
+ *   Copyright 2007-2008 by Apple Inc.
+ *   Copyright 1997-2006 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
- *   property of Easy Software Products and are protected by Federal
- *   copyright law.  Distribution and use rights are outlined in the file
- *   "LICENSE.txt" which should have been included with this file.  If this
- *   file is missing or damaged please contact Easy Software Products
- *   at:
- *
- *       Attn: CUPS Licensing Information
- *       Easy Software Products
- *       44141 Airport View Drive, Suite 204
- *       Hollywood, Maryland 20636-3111 USA
- *
- *       Voice: (301) 373-9603
- *       EMail: cups-info@cups.org
- *         WWW: http://www.cups.org
+ *   property of Apple Inc. and are protected by Federal copyright
+ *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+ *   which should have been included with this file.  If this file is
+ *   file is missing or damaged, see the license at "http://www.cups.org/".
  *
  *   This file is subject to the Apple OS-Developed Software exception.
  *
  * Contents:
  *
- *   cupsTempFd()   - Create a temporary file.
- *   cupsTempFile() - Generate a temporary filename.
+ *   cupsTempFd()    - Creates a temporary file.
+ *   cupsTempFile()  - Generates a temporary filename.
+ *   cupsTempFile2() - Creates a temporary CUPS file.
  */
 
 /*
  * Include necessary headers...
  */
 
-#include "cups.h"
-#include "string.h"
+#include "globals.h"
 #include "debug.h"
 #include <stdlib.h>
-#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 
 
 /*
- * 'cupsTempFd()' - Create a temporary file.
+ * 'cupsTempFd()' - Creates a temporary file.
+ *
+ * The temporary filename is returned in the filename buffer.
+ * The temporary file is opened for reading and writing.
  */
 
-int                                    /* O - New file descriptor */
+int                                    /* O - New file descriptor or -1 on error */
 cupsTempFd(char *filename,             /* I - Pointer to buffer */
            int  len)                   /* I - Size of buffer */
 {
   int          fd;                     /* File descriptor for temp file */
+  int          tries;                  /* Number of tries */
+  const char   *tmpdir;                /* TMPDIR environment var */
 #ifdef WIN32
-  char         tmpdir[1024];           /* Windows temporary directory */
+  char         tmppath[1024];          /* Windows temporary directory */
   DWORD                curtime;                /* Current time */
 #else
-  char         *tmpdir;                /* TMPDIR environment var */
   struct timeval curtime;              /* Current time */
 #endif /* WIN32 */
-  static char  buf[1024] = "";         /* Buffer if you pass in NULL and 0 */
 
 
  /*
-  * See if a filename was specified...
+  * See if TMPDIR is defined...
   */
 
-  if (filename == NULL)
+#ifdef WIN32
+  if ((tmpdir = getenv("TEMP")) == NULL)
   {
-    filename = buf;
-    len      = sizeof(buf);
+    GetTempPath(sizeof(tmppath), tmppath);
+    tmpdir = tmppath;
   }
-
+#else
  /*
-  * See if TMPDIR is defined...
+  * Previously we put root temporary files in the default CUPS temporary
+  * directory under /var/spool/cups.  However, since the scheduler cleans
+  * out temporary files there and runs independently of the user apps, we
+  * don't want to use it unless specifically told to by cupsd.
   */
 
-#ifdef WIN32
-  GetTempPath(sizeof(tmpdir), tmpdir);
-#else
   if ((tmpdir = getenv("TMPDIR")) == NULL)
-  {
-   /*
-    * Put root temp files in restricted temp directory...
-    */
-
-    if (getuid() == 0)
-      tmpdir = CUPS_REQUESTS "/tmp";
-    else
-      tmpdir = "/var/tmp";
-  }
+#  ifdef __APPLE__
+    tmpdir = "/private/tmp";           /* /tmp is a symlink to /private/tmp */
+#  else
+    tmpdir = "/tmp";
+#  endif /* __APPLE__ */
 #endif /* WIN32 */
 
  /*
   * Make the temporary name using the specified directory...
   */
 
+  tries = 0;
+
   do
   {
 #ifdef WIN32
@@ -108,13 +99,14 @@ cupsTempFd(char *filename,         /* I - Pointer to buffer */
     * Get the current time of day...
     */
 
-    curtime = GetTickCount();
+    curtime =  GetTickCount() + tries;
 
    /*
     * Format a string using the hex time values...
     */
 
-    snprintf(filename, len - 1, "%s/%08lx", tmpdir, curtime);
+    snprintf(filename, len - 1, "%s/%05lx%08lx", tmpdir,
+             GetCurrentProcessId(), curtime);
 #else
    /*
     * Get the current time of day...
@@ -126,8 +118,8 @@ cupsTempFd(char *filename,          /* I - Pointer to buffer */
     * Format a string using the hex time values...
     */
 
-    snprintf(filename, len - 1, "%s/%08lx%05lx", tmpdir,
-             curtime.tv_sec, curtime.tv_usec);
+    snprintf(filename, len - 1, "%s/%05x%08lx", tmpdir, (unsigned)getpid(),
+             (unsigned long)(curtime.tv_sec + curtime.tv_usec + tries));
 #endif /* WIN32 */
 
    /*
@@ -135,16 +127,21 @@ cupsTempFd(char *filename,                /* I - Pointer to buffer */
     * stomp on an existing file or someone's symlink crack...
     */
 
-#ifdef O_NOFOLLOW
+#ifdef WIN32
+    fd = open(filename, _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY,
+              _S_IREAD | _S_IWRITE);
+#elif defined(O_NOFOLLOW)
     fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
 #else
     fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
-#endif /* O_NOFOLLOW */
+#endif /* WIN32 */
 
-    if (fd < 0 && (errno == EPERM || errno == ENOENT))
-      break; /* Stop immediately if permission denied or the dir doesn't exist! */
+    if (fd < 0 && errno != EEXIST)
+      break;
+
+    tries ++;
   }
-  while (fd < 0);
+  while (fd < 0 && tries < 1000);
 
  /*
   * Return the file descriptor...
@@ -155,15 +152,21 @@ cupsTempFd(char *filename,                /* I - Pointer to buffer */
 
 
 /*
- * 'cupsTempFile()' - Generate a temporary filename.
+ * 'cupsTempFile()' - Generates a temporary filename.
+ *
+ * The temporary filename is returned in the filename buffer.
+ * This function is deprecated - use @link cupsTempFd@ or
+ * @link cupsTempFile2@ instead.
+ *
+ * @deprecated@
  */
 
-char *                                 /* O - Filename */
+char *                                 /* O - Filename or @code NULL@ on error */
 cupsTempFile(char *filename,           /* I - Pointer to buffer */
              int  len)                 /* I - Size of buffer */
 {
   int          fd;                     /* File descriptor for temp file */
-  static char  buf[1024] = "";         /* Buffer if you pass in NULL and 0 */
+  _cups_globals_t *cg = _cupsGlobals();        /* Pointer to library globals */
 
 
  /*
@@ -172,8 +175,8 @@ cupsTempFile(char *filename,                /* I - Pointer to buffer */
 
   if (filename == NULL)
   {
-    filename = buf;
-    len      = sizeof(buf);
+    filename = cg->tempfile;
+    len      = sizeof(cg->tempfile);
   }
 
  /*
@@ -198,5 +201,35 @@ cupsTempFile(char *filename,               /* I - Pointer to buffer */
 
 
 /*
- * End of "$Id: tempfile.c,v 1.4 2002/03/01 19:53:30 mike Exp $".
+ * 'cupsTempFile2()' - Creates a temporary CUPS file.
+ *
+ * The temporary filename is returned in the filename buffer.
+ * The temporary file is opened for writing.
+ *
+ * @since CUPS 1.2/Mac OS X 10.5@
+ */
+
+cups_file_t *                          /* O - CUPS file or @code NULL@ on error */
+cupsTempFile2(char *filename,          /* I - Pointer to buffer */
+              int  len)                        /* I - Size of buffer */
+{
+  cups_file_t  *file;                  /* CUPS file */
+  int          fd;                     /* File descriptor */
+
+
+  if ((fd = cupsTempFd(filename, len)) < 0)
+    return (NULL);
+  else if ((file = cupsFileOpenFd(fd, "w")) == NULL)
+  {
+    close(fd);
+    unlink(filename);
+    return (NULL);
+  }
+  else
+    return (file);
+}
+
+
+/*
+ * End of "$Id$".
  */