Coverage Report

Created: 2022-10-31 07:00

/src/cups/cups/tempfile.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Temp file utilities for CUPS.
3
 *
4
 * Copyright © 2007-2018 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
0
{
42
0
  int   fd;     /* File descriptor for temp file */
43
0
  int   tries;      /* Number of tries */
44
0
  const char  *tmpdir;    /* TMPDIR environment var */
45
#if defined(__APPLE__) || defined(_WIN32)
46
  char    tmppath[1024];    /* Temporary directory */
47
#endif /* __APPLE__ || _WIN32 */
48
#ifdef _WIN32
49
  DWORD   curtime;    /* Current time */
50
#else
51
0
  struct timeval curtime;   /* Current time */
52
0
#endif /* _WIN32 */
53
54
55
 /*
56
  * See if TMPDIR is defined...
57
  */
58
59
#ifdef _WIN32
60
  if ((tmpdir = getenv("TEMP")) == NULL)
61
  {
62
    GetTempPath(sizeof(tmppath), tmppath);
63
    tmpdir = tmppath;
64
  }
65
66
#elif defined(__APPLE__)
67
 /*
68
  * On macOS and iOS, the TMPDIR environment variable is not always the best
69
  * location to place temporary files due to sandboxing.  Instead, the confstr
70
  * function should be called to get the proper per-user, per-process TMPDIR
71
  * value.
72
  */
73
74
  if ((tmpdir = getenv("TMPDIR")) != NULL && access(tmpdir, W_OK))
75
    tmpdir = NULL;
76
77
  if (!tmpdir)
78
  {
79
    if (confstr(_CS_DARWIN_USER_TEMP_DIR, tmppath, sizeof(tmppath)))
80
      tmpdir = tmppath;
81
    else
82
      tmpdir = "/private/tmp";    /* This should never happen */
83
  }
84
85
#else
86
 /*
87
  * Previously we put root temporary files in the default CUPS temporary
88
  * directory under /var/spool/cups.  However, since the scheduler cleans
89
  * out temporary files there and runs independently of the user apps, we
90
  * don't want to use it unless specifically told to by cupsd.
91
  */
92
93
0
  if ((tmpdir = getenv("TMPDIR")) == NULL)
94
0
    tmpdir = "/tmp";
95
0
#endif /* _WIN32 */
96
97
 /*
98
  * Make the temporary name using the specified directory...
99
  */
100
101
0
  tries = 0;
102
103
0
  do
104
0
  {
105
#ifdef _WIN32
106
   /*
107
    * Get the current time of day...
108
    */
109
110
    curtime =  GetTickCount() + tries;
111
112
   /*
113
    * Format a string using the hex time values...
114
    */
115
116
    snprintf(filename, (size_t)len - 1, "%s/%05lx%08lx", tmpdir, GetCurrentProcessId(), curtime);
117
#else
118
   /*
119
    * Get the current time of day...
120
    */
121
122
0
    gettimeofday(&curtime, NULL);
123
124
   /*
125
    * Format a string using the hex time values...
126
    */
127
128
0
    snprintf(filename, (size_t)len - 1, "%s/%05x%08x", tmpdir, (unsigned)getpid(), (unsigned)(curtime.tv_sec + curtime.tv_usec + tries));
129
0
#endif /* _WIN32 */
130
131
   /*
132
    * Open the file in "exclusive" mode, making sure that we don't
133
    * stomp on an existing file or someone's symlink crack...
134
    */
135
136
#ifdef _WIN32
137
    fd = open(filename, _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY,
138
              _S_IREAD | _S_IWRITE);
139
#elif defined(O_NOFOLLOW)
140
0
    fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
141
#else
142
    fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
143
#endif /* _WIN32 */
144
145
0
    if (fd < 0 && errno != EEXIST)
146
0
      break;
147
148
0
    tries ++;
149
0
  }
150
0
  while (fd < 0 && tries < 1000);
151
152
 /*
153
  * Return the file descriptor...
154
  */
155
156
0
  return (fd);
157
0
}
158
159
160
/*
161
 * 'cupsTempFile()' - Generates a temporary filename.
162
 *
163
 * The temporary filename is returned in the filename buffer.
164
 * This function is deprecated and will no longer generate a temporary
165
 * filename - use @link cupsTempFd@ or @link cupsTempFile2@ instead.
166
 *
167
 * @deprecated@
168
 */
169
170
char *          /* O - Filename or @code NULL@ on error */
171
cupsTempFile(char *filename,    /* I - Pointer to buffer */
172
             int  len)      /* I - Size of buffer */
173
0
{
174
0
  (void)len;
175
176
0
  if (filename)
177
0
    *filename = '\0';
178
179
0
  return (NULL);
180
0
}
181
182
183
/*
184
 * 'cupsTempFile2()' - Creates a temporary CUPS file.
185
 *
186
 * The temporary filename is returned in the filename buffer.
187
 * The temporary file is opened for writing.
188
 *
189
 * @since CUPS 1.2/macOS 10.5@
190
 */
191
192
cups_file_t *       /* O - CUPS file or @code NULL@ on error */
193
cupsTempFile2(char *filename,   /* I - Pointer to buffer */
194
              int  len)     /* I - Size of buffer */
195
0
{
196
0
  cups_file_t *file;      /* CUPS file */
197
0
  int   fd;     /* File descriptor */
198
199
200
0
  if ((fd = cupsTempFd(filename, len)) < 0)
201
0
    return (NULL);
202
0
  else if ((file = cupsFileOpenFd(fd, "w")) == NULL)
203
0
  {
204
0
    close(fd);
205
0
    unlink(filename);
206
0
    return (NULL);
207
0
  }
208
0
  else
209
0
    return (file);
210
0
}