xref: /aosp_15_r20/external/libcups/scheduler/file.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * File functions for the CUPS scheduler.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2007-2014 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
6*5e7646d2SAndroid Build Coastguard Worker  *
7*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker  * information.
9*5e7646d2SAndroid Build Coastguard Worker  */
10*5e7646d2SAndroid Build Coastguard Worker 
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker  */
14*5e7646d2SAndroid Build Coastguard Worker 
15*5e7646d2SAndroid Build Coastguard Worker #include "cupsd.h"
16*5e7646d2SAndroid Build Coastguard Worker #include <cups/dir.h>
17*5e7646d2SAndroid Build Coastguard Worker #include <fnmatch.h>
18*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_REMOVEFILE
19*5e7646d2SAndroid Build Coastguard Worker #  include <removefile.h>
20*5e7646d2SAndroid Build Coastguard Worker #else
21*5e7646d2SAndroid Build Coastguard Worker static int	overwrite_data(int fd, const char *buffer, int bufsize,
22*5e7646d2SAndroid Build Coastguard Worker 		               int filesize);
23*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_REMOVEFILE */
24*5e7646d2SAndroid Build Coastguard Worker 
25*5e7646d2SAndroid Build Coastguard Worker 
26*5e7646d2SAndroid Build Coastguard Worker /*
27*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdCleanFiles()' - Clean out old files.
28*5e7646d2SAndroid Build Coastguard Worker  */
29*5e7646d2SAndroid Build Coastguard Worker 
30*5e7646d2SAndroid Build Coastguard Worker void
cupsdCleanFiles(const char * path,const char * pattern)31*5e7646d2SAndroid Build Coastguard Worker cupsdCleanFiles(const char *path,	/* I - Directory to clean */
32*5e7646d2SAndroid Build Coastguard Worker                 const char *pattern)	/* I - Filename pattern or NULL */
33*5e7646d2SAndroid Build Coastguard Worker {
34*5e7646d2SAndroid Build Coastguard Worker   cups_dir_t	*dir;			/* Directory */
35*5e7646d2SAndroid Build Coastguard Worker   cups_dentry_t	*dent;			/* Directory entry */
36*5e7646d2SAndroid Build Coastguard Worker   char		filename[1024];		/* Filename */
37*5e7646d2SAndroid Build Coastguard Worker   int		status;			/* Status from unlink/rmdir */
38*5e7646d2SAndroid Build Coastguard Worker 
39*5e7646d2SAndroid Build Coastguard Worker 
40*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG,
41*5e7646d2SAndroid Build Coastguard Worker                   "cupsdCleanFiles(path=\"%s\", pattern=\"%s\")", path,
42*5e7646d2SAndroid Build Coastguard Worker 		  pattern ? pattern : "(null)");
43*5e7646d2SAndroid Build Coastguard Worker 
44*5e7646d2SAndroid Build Coastguard Worker   if ((dir = cupsDirOpen(path)) == NULL)
45*5e7646d2SAndroid Build Coastguard Worker   {
46*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open directory \"%s\" - %s",
47*5e7646d2SAndroid Build Coastguard Worker 		    path, strerror(errno));
48*5e7646d2SAndroid Build Coastguard Worker     return;
49*5e7646d2SAndroid Build Coastguard Worker   }
50*5e7646d2SAndroid Build Coastguard Worker 
51*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_INFO, "Cleaning out old files in \"%s\".", path);
52*5e7646d2SAndroid Build Coastguard Worker 
53*5e7646d2SAndroid Build Coastguard Worker   while ((dent = cupsDirRead(dir)) != NULL)
54*5e7646d2SAndroid Build Coastguard Worker   {
55*5e7646d2SAndroid Build Coastguard Worker     if (pattern && fnmatch(pattern, dent->filename, 0))
56*5e7646d2SAndroid Build Coastguard Worker       continue;
57*5e7646d2SAndroid Build Coastguard Worker 
58*5e7646d2SAndroid Build Coastguard Worker     snprintf(filename, sizeof(filename), "%s/%s", path, dent->filename);
59*5e7646d2SAndroid Build Coastguard Worker 
60*5e7646d2SAndroid Build Coastguard Worker     if (S_ISDIR(dent->fileinfo.st_mode))
61*5e7646d2SAndroid Build Coastguard Worker     {
62*5e7646d2SAndroid Build Coastguard Worker       cupsdCleanFiles(filename, pattern);
63*5e7646d2SAndroid Build Coastguard Worker 
64*5e7646d2SAndroid Build Coastguard Worker       status = rmdir(filename);
65*5e7646d2SAndroid Build Coastguard Worker     }
66*5e7646d2SAndroid Build Coastguard Worker     else
67*5e7646d2SAndroid Build Coastguard Worker       status = cupsdUnlinkOrRemoveFile(filename);
68*5e7646d2SAndroid Build Coastguard Worker 
69*5e7646d2SAndroid Build Coastguard Worker     if (status)
70*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to remove \"%s\" - %s", filename,
71*5e7646d2SAndroid Build Coastguard Worker 		      strerror(errno));
72*5e7646d2SAndroid Build Coastguard Worker   }
73*5e7646d2SAndroid Build Coastguard Worker 
74*5e7646d2SAndroid Build Coastguard Worker   cupsDirClose(dir);
75*5e7646d2SAndroid Build Coastguard Worker }
76*5e7646d2SAndroid Build Coastguard Worker 
77*5e7646d2SAndroid Build Coastguard Worker 
78*5e7646d2SAndroid Build Coastguard Worker /*
79*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdCloseCreatedConfFile()' - Close a created configuration file and move
80*5e7646d2SAndroid Build Coastguard Worker  *                                 into place.
81*5e7646d2SAndroid Build Coastguard Worker  */
82*5e7646d2SAndroid Build Coastguard Worker 
83*5e7646d2SAndroid Build Coastguard Worker int					/* O - 0 on success, -1 on error */
cupsdCloseCreatedConfFile(cups_file_t * fp,const char * filename)84*5e7646d2SAndroid Build Coastguard Worker cupsdCloseCreatedConfFile(
85*5e7646d2SAndroid Build Coastguard Worker     cups_file_t *fp,			/* I - File to close */
86*5e7646d2SAndroid Build Coastguard Worker     const char  *filename)		/* I - Filename */
87*5e7646d2SAndroid Build Coastguard Worker {
88*5e7646d2SAndroid Build Coastguard Worker   char	newfile[1024],			/* filename.N */
89*5e7646d2SAndroid Build Coastguard Worker 	oldfile[1024];			/* filename.O */
90*5e7646d2SAndroid Build Coastguard Worker 
91*5e7646d2SAndroid Build Coastguard Worker 
92*5e7646d2SAndroid Build Coastguard Worker  /*
93*5e7646d2SAndroid Build Coastguard Worker   * Synchronize changes to disk if SyncOnClose is enabled.
94*5e7646d2SAndroid Build Coastguard Worker   */
95*5e7646d2SAndroid Build Coastguard Worker 
96*5e7646d2SAndroid Build Coastguard Worker   if (SyncOnClose)
97*5e7646d2SAndroid Build Coastguard Worker   {
98*5e7646d2SAndroid Build Coastguard Worker     if (cupsFileFlush(fp))
99*5e7646d2SAndroid Build Coastguard Worker     {
100*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to write changes to \"%s\": %s",
101*5e7646d2SAndroid Build Coastguard Worker 		      filename, strerror(errno));
102*5e7646d2SAndroid Build Coastguard Worker       cupsFileClose(fp);
103*5e7646d2SAndroid Build Coastguard Worker       return (-1);
104*5e7646d2SAndroid Build Coastguard Worker     }
105*5e7646d2SAndroid Build Coastguard Worker 
106*5e7646d2SAndroid Build Coastguard Worker     if (fsync(cupsFileNumber(fp)))
107*5e7646d2SAndroid Build Coastguard Worker     {
108*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to sync changes to \"%s\": %s",
109*5e7646d2SAndroid Build Coastguard Worker 		      filename, strerror(errno));
110*5e7646d2SAndroid Build Coastguard Worker       cupsFileClose(fp);
111*5e7646d2SAndroid Build Coastguard Worker       return (-1);
112*5e7646d2SAndroid Build Coastguard Worker     }
113*5e7646d2SAndroid Build Coastguard Worker   }
114*5e7646d2SAndroid Build Coastguard Worker 
115*5e7646d2SAndroid Build Coastguard Worker  /*
116*5e7646d2SAndroid Build Coastguard Worker   * First close the file...
117*5e7646d2SAndroid Build Coastguard Worker   */
118*5e7646d2SAndroid Build Coastguard Worker 
119*5e7646d2SAndroid Build Coastguard Worker   if (cupsFileClose(fp))
120*5e7646d2SAndroid Build Coastguard Worker     return (-1);
121*5e7646d2SAndroid Build Coastguard Worker 
122*5e7646d2SAndroid Build Coastguard Worker  /*
123*5e7646d2SAndroid Build Coastguard Worker   * Then remove "filename.O", rename "filename" to "filename.O", and rename
124*5e7646d2SAndroid Build Coastguard Worker   * "filename.N" to "filename".
125*5e7646d2SAndroid Build Coastguard Worker   */
126*5e7646d2SAndroid Build Coastguard Worker 
127*5e7646d2SAndroid Build Coastguard Worker   snprintf(newfile, sizeof(newfile), "%s.N", filename);
128*5e7646d2SAndroid Build Coastguard Worker   snprintf(oldfile, sizeof(oldfile), "%s.O", filename);
129*5e7646d2SAndroid Build Coastguard Worker 
130*5e7646d2SAndroid Build Coastguard Worker   if ((cupsdUnlinkOrRemoveFile(oldfile) && errno != ENOENT) ||
131*5e7646d2SAndroid Build Coastguard Worker       (rename(filename, oldfile) && errno != ENOENT) ||
132*5e7646d2SAndroid Build Coastguard Worker       rename(newfile, filename))
133*5e7646d2SAndroid Build Coastguard Worker   {
134*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to finalize \"%s\": %s",
135*5e7646d2SAndroid Build Coastguard Worker                     filename, strerror(errno));
136*5e7646d2SAndroid Build Coastguard Worker     return (-1);
137*5e7646d2SAndroid Build Coastguard Worker   }
138*5e7646d2SAndroid Build Coastguard Worker 
139*5e7646d2SAndroid Build Coastguard Worker   return (0);
140*5e7646d2SAndroid Build Coastguard Worker }
141*5e7646d2SAndroid Build Coastguard Worker 
142*5e7646d2SAndroid Build Coastguard Worker 
143*5e7646d2SAndroid Build Coastguard Worker /*
144*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdClosePipe()' - Close a pipe as necessary.
145*5e7646d2SAndroid Build Coastguard Worker  */
146*5e7646d2SAndroid Build Coastguard Worker 
147*5e7646d2SAndroid Build Coastguard Worker void
cupsdClosePipe(int * fds)148*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(int *fds)		/* I - Pipe file descriptors (2) */
149*5e7646d2SAndroid Build Coastguard Worker {
150*5e7646d2SAndroid Build Coastguard Worker  /*
151*5e7646d2SAndroid Build Coastguard Worker   * Close file descriptors as needed...
152*5e7646d2SAndroid Build Coastguard Worker   */
153*5e7646d2SAndroid Build Coastguard Worker 
154*5e7646d2SAndroid Build Coastguard Worker   if (fds[0] >= 0)
155*5e7646d2SAndroid Build Coastguard Worker   {
156*5e7646d2SAndroid Build Coastguard Worker     close(fds[0]);
157*5e7646d2SAndroid Build Coastguard Worker     fds[0] = -1;
158*5e7646d2SAndroid Build Coastguard Worker   }
159*5e7646d2SAndroid Build Coastguard Worker 
160*5e7646d2SAndroid Build Coastguard Worker   if (fds[1] >= 0)
161*5e7646d2SAndroid Build Coastguard Worker   {
162*5e7646d2SAndroid Build Coastguard Worker     close(fds[1]);
163*5e7646d2SAndroid Build Coastguard Worker     fds[1] = -1;
164*5e7646d2SAndroid Build Coastguard Worker   }
165*5e7646d2SAndroid Build Coastguard Worker }
166*5e7646d2SAndroid Build Coastguard Worker 
167*5e7646d2SAndroid Build Coastguard Worker 
168*5e7646d2SAndroid Build Coastguard Worker /*
169*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdCreateConfFile()' - Create a configuration file safely.
170*5e7646d2SAndroid Build Coastguard Worker  */
171*5e7646d2SAndroid Build Coastguard Worker 
172*5e7646d2SAndroid Build Coastguard Worker cups_file_t *				/* O - File pointer */
cupsdCreateConfFile(const char * filename,mode_t mode)173*5e7646d2SAndroid Build Coastguard Worker cupsdCreateConfFile(
174*5e7646d2SAndroid Build Coastguard Worker     const char *filename,		/* I - Filename */
175*5e7646d2SAndroid Build Coastguard Worker     mode_t     mode)			/* I - Permissions */
176*5e7646d2SAndroid Build Coastguard Worker {
177*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*fp;			/* File pointer */
178*5e7646d2SAndroid Build Coastguard Worker   char		newfile[1024];		/* filename.N */
179*5e7646d2SAndroid Build Coastguard Worker 
180*5e7646d2SAndroid Build Coastguard Worker 
181*5e7646d2SAndroid Build Coastguard Worker   snprintf(newfile, sizeof(newfile), "%s.N", filename);
182*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsFileOpen(newfile, "w")) == NULL)
183*5e7646d2SAndroid Build Coastguard Worker   {
184*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create \"%s\": %s", newfile,
185*5e7646d2SAndroid Build Coastguard Worker 		    strerror(errno));
186*5e7646d2SAndroid Build Coastguard Worker   }
187*5e7646d2SAndroid Build Coastguard Worker   else
188*5e7646d2SAndroid Build Coastguard Worker   {
189*5e7646d2SAndroid Build Coastguard Worker     if (!getuid() && fchown(cupsFileNumber(fp), getuid(), Group))
190*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_WARN, "Unable to change group for \"%s\": %s",
191*5e7646d2SAndroid Build Coastguard Worker 		      newfile, strerror(errno));
192*5e7646d2SAndroid Build Coastguard Worker 
193*5e7646d2SAndroid Build Coastguard Worker     if (fchmod(cupsFileNumber(fp), mode))
194*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_WARN,
195*5e7646d2SAndroid Build Coastguard Worker                       "Unable to change permissions for \"%s\": %s",
196*5e7646d2SAndroid Build Coastguard Worker 		      newfile, strerror(errno));
197*5e7646d2SAndroid Build Coastguard Worker   }
198*5e7646d2SAndroid Build Coastguard Worker 
199*5e7646d2SAndroid Build Coastguard Worker   return (fp);
200*5e7646d2SAndroid Build Coastguard Worker }
201*5e7646d2SAndroid Build Coastguard Worker 
202*5e7646d2SAndroid Build Coastguard Worker 
203*5e7646d2SAndroid Build Coastguard Worker /*
204*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdOpenConfFile()' - Open a configuration file.
205*5e7646d2SAndroid Build Coastguard Worker  *
206*5e7646d2SAndroid Build Coastguard Worker  * This function looks for "filename.O" if "filename" does not exist and does
207*5e7646d2SAndroid Build Coastguard Worker  * a rename as needed.
208*5e7646d2SAndroid Build Coastguard Worker  */
209*5e7646d2SAndroid Build Coastguard Worker 
210*5e7646d2SAndroid Build Coastguard Worker cups_file_t *				/* O - File pointer */
cupsdOpenConfFile(const char * filename)211*5e7646d2SAndroid Build Coastguard Worker cupsdOpenConfFile(const char *filename)	/* I - Filename */
212*5e7646d2SAndroid Build Coastguard Worker {
213*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*fp;			/* File pointer */
214*5e7646d2SAndroid Build Coastguard Worker 
215*5e7646d2SAndroid Build Coastguard Worker 
216*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsFileOpen(filename, "r")) == NULL)
217*5e7646d2SAndroid Build Coastguard Worker   {
218*5e7646d2SAndroid Build Coastguard Worker     if (errno == ENOENT)
219*5e7646d2SAndroid Build Coastguard Worker     {
220*5e7646d2SAndroid Build Coastguard Worker      /*
221*5e7646d2SAndroid Build Coastguard Worker       * Try opening the backup file...
222*5e7646d2SAndroid Build Coastguard Worker       */
223*5e7646d2SAndroid Build Coastguard Worker 
224*5e7646d2SAndroid Build Coastguard Worker       char	oldfile[1024];		/* filename.O */
225*5e7646d2SAndroid Build Coastguard Worker 
226*5e7646d2SAndroid Build Coastguard Worker       snprintf(oldfile, sizeof(oldfile), "%s.O", filename);
227*5e7646d2SAndroid Build Coastguard Worker       fp = cupsFileOpen(oldfile, "r");
228*5e7646d2SAndroid Build Coastguard Worker     }
229*5e7646d2SAndroid Build Coastguard Worker     else
230*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"%s\": %s", filename,
231*5e7646d2SAndroid Build Coastguard Worker 		      strerror(errno));
232*5e7646d2SAndroid Build Coastguard Worker   }
233*5e7646d2SAndroid Build Coastguard Worker 
234*5e7646d2SAndroid Build Coastguard Worker   return (fp);
235*5e7646d2SAndroid Build Coastguard Worker }
236*5e7646d2SAndroid Build Coastguard Worker 
237*5e7646d2SAndroid Build Coastguard Worker 
238*5e7646d2SAndroid Build Coastguard Worker /*
239*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdOpenPipe()' - Create a pipe which is closed on exec.
240*5e7646d2SAndroid Build Coastguard Worker  */
241*5e7646d2SAndroid Build Coastguard Worker 
242*5e7646d2SAndroid Build Coastguard Worker int					/* O - 0 on success, -1 on error */
cupsdOpenPipe(int * fds)243*5e7646d2SAndroid Build Coastguard Worker cupsdOpenPipe(int *fds)			/* O - Pipe file descriptors (2) */
244*5e7646d2SAndroid Build Coastguard Worker {
245*5e7646d2SAndroid Build Coastguard Worker  /*
246*5e7646d2SAndroid Build Coastguard Worker   * Create the pipe...
247*5e7646d2SAndroid Build Coastguard Worker   */
248*5e7646d2SAndroid Build Coastguard Worker 
249*5e7646d2SAndroid Build Coastguard Worker   if (pipe(fds))
250*5e7646d2SAndroid Build Coastguard Worker   {
251*5e7646d2SAndroid Build Coastguard Worker     fds[0] = -1;
252*5e7646d2SAndroid Build Coastguard Worker     fds[1] = -1;
253*5e7646d2SAndroid Build Coastguard Worker 
254*5e7646d2SAndroid Build Coastguard Worker     return (-1);
255*5e7646d2SAndroid Build Coastguard Worker   }
256*5e7646d2SAndroid Build Coastguard Worker 
257*5e7646d2SAndroid Build Coastguard Worker  /*
258*5e7646d2SAndroid Build Coastguard Worker   * Set the "close on exec" flag on each end of the pipe...
259*5e7646d2SAndroid Build Coastguard Worker   */
260*5e7646d2SAndroid Build Coastguard Worker 
261*5e7646d2SAndroid Build Coastguard Worker   if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC))
262*5e7646d2SAndroid Build Coastguard Worker   {
263*5e7646d2SAndroid Build Coastguard Worker     close(fds[0]);
264*5e7646d2SAndroid Build Coastguard Worker     close(fds[1]);
265*5e7646d2SAndroid Build Coastguard Worker 
266*5e7646d2SAndroid Build Coastguard Worker     fds[0] = -1;
267*5e7646d2SAndroid Build Coastguard Worker     fds[1] = -1;
268*5e7646d2SAndroid Build Coastguard Worker 
269*5e7646d2SAndroid Build Coastguard Worker     return (-1);
270*5e7646d2SAndroid Build Coastguard Worker   }
271*5e7646d2SAndroid Build Coastguard Worker 
272*5e7646d2SAndroid Build Coastguard Worker   if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC))
273*5e7646d2SAndroid Build Coastguard Worker   {
274*5e7646d2SAndroid Build Coastguard Worker     close(fds[0]);
275*5e7646d2SAndroid Build Coastguard Worker     close(fds[1]);
276*5e7646d2SAndroid Build Coastguard Worker 
277*5e7646d2SAndroid Build Coastguard Worker     fds[0] = -1;
278*5e7646d2SAndroid Build Coastguard Worker     fds[1] = -1;
279*5e7646d2SAndroid Build Coastguard Worker 
280*5e7646d2SAndroid Build Coastguard Worker     return (-1);
281*5e7646d2SAndroid Build Coastguard Worker   }
282*5e7646d2SAndroid Build Coastguard Worker 
283*5e7646d2SAndroid Build Coastguard Worker  /*
284*5e7646d2SAndroid Build Coastguard Worker   * Return 0 indicating success...
285*5e7646d2SAndroid Build Coastguard Worker   */
286*5e7646d2SAndroid Build Coastguard Worker 
287*5e7646d2SAndroid Build Coastguard Worker   return (0);
288*5e7646d2SAndroid Build Coastguard Worker }
289*5e7646d2SAndroid Build Coastguard Worker 
290*5e7646d2SAndroid Build Coastguard Worker 
291*5e7646d2SAndroid Build Coastguard Worker /*
292*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdRemoveFile()' - Remove a file securely.
293*5e7646d2SAndroid Build Coastguard Worker  */
294*5e7646d2SAndroid Build Coastguard Worker 
295*5e7646d2SAndroid Build Coastguard Worker int					/* O - 0 on success, -1 on error */
cupsdRemoveFile(const char * filename)296*5e7646d2SAndroid Build Coastguard Worker cupsdRemoveFile(const char *filename)	/* I - File to remove */
297*5e7646d2SAndroid Build Coastguard Worker {
298*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_REMOVEFILE
299*5e7646d2SAndroid Build Coastguard Worker  /*
300*5e7646d2SAndroid Build Coastguard Worker   * See if the file exists...
301*5e7646d2SAndroid Build Coastguard Worker   */
302*5e7646d2SAndroid Build Coastguard Worker 
303*5e7646d2SAndroid Build Coastguard Worker   if (access(filename, 0))
304*5e7646d2SAndroid Build Coastguard Worker     return (0);
305*5e7646d2SAndroid Build Coastguard Worker 
306*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG, "Securely removing \"%s\".", filename);
307*5e7646d2SAndroid Build Coastguard Worker 
308*5e7646d2SAndroid Build Coastguard Worker  /*
309*5e7646d2SAndroid Build Coastguard Worker   * Remove the file...
310*5e7646d2SAndroid Build Coastguard Worker   */
311*5e7646d2SAndroid Build Coastguard Worker 
312*5e7646d2SAndroid Build Coastguard Worker   return (removefile(filename, NULL, REMOVEFILE_SECURE_1_PASS));
313*5e7646d2SAndroid Build Coastguard Worker 
314*5e7646d2SAndroid Build Coastguard Worker #else
315*5e7646d2SAndroid Build Coastguard Worker   int			fd;		/* File descriptor */
316*5e7646d2SAndroid Build Coastguard Worker   struct stat		info;		/* File information */
317*5e7646d2SAndroid Build Coastguard Worker   char			buffer[512];	/* Data buffer */
318*5e7646d2SAndroid Build Coastguard Worker   int			i;		/* Looping var */
319*5e7646d2SAndroid Build Coastguard Worker 
320*5e7646d2SAndroid Build Coastguard Worker 
321*5e7646d2SAndroid Build Coastguard Worker  /*
322*5e7646d2SAndroid Build Coastguard Worker   * See if the file exists...
323*5e7646d2SAndroid Build Coastguard Worker   */
324*5e7646d2SAndroid Build Coastguard Worker 
325*5e7646d2SAndroid Build Coastguard Worker   if (access(filename, 0))
326*5e7646d2SAndroid Build Coastguard Worker     return (0);
327*5e7646d2SAndroid Build Coastguard Worker 
328*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG, "Securely removing \"%s\".", filename);
329*5e7646d2SAndroid Build Coastguard Worker 
330*5e7646d2SAndroid Build Coastguard Worker  /*
331*5e7646d2SAndroid Build Coastguard Worker   * First open the file for writing in exclusive mode.
332*5e7646d2SAndroid Build Coastguard Worker   */
333*5e7646d2SAndroid Build Coastguard Worker 
334*5e7646d2SAndroid Build Coastguard Worker   if ((fd = open(filename, O_WRONLY | O_EXCL)) < 0)
335*5e7646d2SAndroid Build Coastguard Worker     return (-1);
336*5e7646d2SAndroid Build Coastguard Worker 
337*5e7646d2SAndroid Build Coastguard Worker  /*
338*5e7646d2SAndroid Build Coastguard Worker   * Delete the file now - it will still be around as long as the file is
339*5e7646d2SAndroid Build Coastguard Worker   * open...
340*5e7646d2SAndroid Build Coastguard Worker   */
341*5e7646d2SAndroid Build Coastguard Worker 
342*5e7646d2SAndroid Build Coastguard Worker   if (unlink(filename))
343*5e7646d2SAndroid Build Coastguard Worker   {
344*5e7646d2SAndroid Build Coastguard Worker     close(fd);
345*5e7646d2SAndroid Build Coastguard Worker     return (-1);
346*5e7646d2SAndroid Build Coastguard Worker   }
347*5e7646d2SAndroid Build Coastguard Worker 
348*5e7646d2SAndroid Build Coastguard Worker  /*
349*5e7646d2SAndroid Build Coastguard Worker   * Then get the file size...
350*5e7646d2SAndroid Build Coastguard Worker   */
351*5e7646d2SAndroid Build Coastguard Worker 
352*5e7646d2SAndroid Build Coastguard Worker   if (fstat(fd, &info))
353*5e7646d2SAndroid Build Coastguard Worker   {
354*5e7646d2SAndroid Build Coastguard Worker     close(fd);
355*5e7646d2SAndroid Build Coastguard Worker     return (-1);
356*5e7646d2SAndroid Build Coastguard Worker   }
357*5e7646d2SAndroid Build Coastguard Worker 
358*5e7646d2SAndroid Build Coastguard Worker  /*
359*5e7646d2SAndroid Build Coastguard Worker   * Overwrite the file with random data.
360*5e7646d2SAndroid Build Coastguard Worker   */
361*5e7646d2SAndroid Build Coastguard Worker 
362*5e7646d2SAndroid Build Coastguard Worker   CUPS_SRAND(time(NULL));
363*5e7646d2SAndroid Build Coastguard Worker 
364*5e7646d2SAndroid Build Coastguard Worker   for (i = 0; i < sizeof(buffer); i ++)
365*5e7646d2SAndroid Build Coastguard Worker     buffer[i] = CUPS_RAND();
366*5e7646d2SAndroid Build Coastguard Worker   if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
367*5e7646d2SAndroid Build Coastguard Worker   {
368*5e7646d2SAndroid Build Coastguard Worker     close(fd);
369*5e7646d2SAndroid Build Coastguard Worker     return (-1);
370*5e7646d2SAndroid Build Coastguard Worker   }
371*5e7646d2SAndroid Build Coastguard Worker 
372*5e7646d2SAndroid Build Coastguard Worker  /*
373*5e7646d2SAndroid Build Coastguard Worker   * Close the file, which will lead to the actual deletion, and return...
374*5e7646d2SAndroid Build Coastguard Worker   */
375*5e7646d2SAndroid Build Coastguard Worker 
376*5e7646d2SAndroid Build Coastguard Worker   return (close(fd));
377*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_REMOVEFILE */
378*5e7646d2SAndroid Build Coastguard Worker }
379*5e7646d2SAndroid Build Coastguard Worker 
380*5e7646d2SAndroid Build Coastguard Worker 
381*5e7646d2SAndroid Build Coastguard Worker /*
382*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdUnlinkOrRemoveFile()' - Unlink or securely remove a file depending
383*5e7646d2SAndroid Build Coastguard Worker  *                               on the configuration.
384*5e7646d2SAndroid Build Coastguard Worker  */
385*5e7646d2SAndroid Build Coastguard Worker 
386*5e7646d2SAndroid Build Coastguard Worker int					/* O - 0 on success, -1 on error */
cupsdUnlinkOrRemoveFile(const char * filename)387*5e7646d2SAndroid Build Coastguard Worker cupsdUnlinkOrRemoveFile(
388*5e7646d2SAndroid Build Coastguard Worker     const char *filename)		/* I - Filename */
389*5e7646d2SAndroid Build Coastguard Worker {
390*5e7646d2SAndroid Build Coastguard Worker   if (Classification)
391*5e7646d2SAndroid Build Coastguard Worker     return (cupsdRemoveFile(filename));
392*5e7646d2SAndroid Build Coastguard Worker   else
393*5e7646d2SAndroid Build Coastguard Worker     return (unlink(filename));
394*5e7646d2SAndroid Build Coastguard Worker }
395*5e7646d2SAndroid Build Coastguard Worker 
396*5e7646d2SAndroid Build Coastguard Worker 
397*5e7646d2SAndroid Build Coastguard Worker #ifndef HAVE_REMOVEFILE
398*5e7646d2SAndroid Build Coastguard Worker /*
399*5e7646d2SAndroid Build Coastguard Worker  * 'overwrite_data()' - Overwrite the data in a file.
400*5e7646d2SAndroid Build Coastguard Worker  */
401*5e7646d2SAndroid Build Coastguard Worker 
402*5e7646d2SAndroid Build Coastguard Worker static int				/* O - 0 on success, -1 on error */
overwrite_data(int fd,const char * buffer,int bufsize,int filesize)403*5e7646d2SAndroid Build Coastguard Worker overwrite_data(int        fd,		/* I - File descriptor */
404*5e7646d2SAndroid Build Coastguard Worker                const char *buffer,	/* I - Buffer to write */
405*5e7646d2SAndroid Build Coastguard Worker 	       int        bufsize,	/* I - Size of buffer */
406*5e7646d2SAndroid Build Coastguard Worker                int        filesize)	/* I - Size of file */
407*5e7646d2SAndroid Build Coastguard Worker {
408*5e7646d2SAndroid Build Coastguard Worker   int	bytes;				/* Bytes to write/written */
409*5e7646d2SAndroid Build Coastguard Worker 
410*5e7646d2SAndroid Build Coastguard Worker 
411*5e7646d2SAndroid Build Coastguard Worker  /*
412*5e7646d2SAndroid Build Coastguard Worker   * Start at the beginning of the file...
413*5e7646d2SAndroid Build Coastguard Worker   */
414*5e7646d2SAndroid Build Coastguard Worker 
415*5e7646d2SAndroid Build Coastguard Worker   if (lseek(fd, 0, SEEK_SET) < 0)
416*5e7646d2SAndroid Build Coastguard Worker     return (-1);
417*5e7646d2SAndroid Build Coastguard Worker 
418*5e7646d2SAndroid Build Coastguard Worker  /*
419*5e7646d2SAndroid Build Coastguard Worker   * Fill the file with the provided data...
420*5e7646d2SAndroid Build Coastguard Worker   */
421*5e7646d2SAndroid Build Coastguard Worker 
422*5e7646d2SAndroid Build Coastguard Worker   while (filesize > 0)
423*5e7646d2SAndroid Build Coastguard Worker   {
424*5e7646d2SAndroid Build Coastguard Worker     if (filesize > bufsize)
425*5e7646d2SAndroid Build Coastguard Worker       bytes = bufsize;
426*5e7646d2SAndroid Build Coastguard Worker     else
427*5e7646d2SAndroid Build Coastguard Worker       bytes = filesize;
428*5e7646d2SAndroid Build Coastguard Worker 
429*5e7646d2SAndroid Build Coastguard Worker     if ((bytes = write(fd, buffer, (size_t)bytes)) < 0)
430*5e7646d2SAndroid Build Coastguard Worker       return (-1);
431*5e7646d2SAndroid Build Coastguard Worker 
432*5e7646d2SAndroid Build Coastguard Worker     filesize -= bytes;
433*5e7646d2SAndroid Build Coastguard Worker   }
434*5e7646d2SAndroid Build Coastguard Worker 
435*5e7646d2SAndroid Build Coastguard Worker  /*
436*5e7646d2SAndroid Build Coastguard Worker   * Force the changes to disk...
437*5e7646d2SAndroid Build Coastguard Worker   */
438*5e7646d2SAndroid Build Coastguard Worker 
439*5e7646d2SAndroid Build Coastguard Worker   return (fsync(fd));
440*5e7646d2SAndroid Build Coastguard Worker }
441*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_REMOVEFILE */
442