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