]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/removefile.c
Merge changes from CUPS 1.4svn-r7874.
[thirdparty/cups.git] / scheduler / removefile.c
CommitLineData
cc0d019f
MS
1/*
2 * "$Id$"
3 *
4 * "Secure" file removal function for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products, all rights reserved.
8 *
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * "LICENSE" which should have been included with this file. If this
13 * file is missing or damaged, see the license at "http://www.cups.org/".
14 *
15 * Contents:
16 *
17 * cupsdRemoveFile() - Remove a file using the 7-pass US DoD method.
18 * overwrite_data() - Overwrite the data in a file.
19 */
20
21/*
22 * Include necessary headers...
23 */
24
25#include "cupsd.h"
26#ifdef HAVE_REMOVEFILE
27# include <removefile.h>
28#else
29static int overwrite_data(int fd, const char *buffer, int bufsize,
30 int filesize);
31#endif /* HAVE_REMOVEFILE */
32
33
34/*
35 * 'cupsdRemoveFile()' - Remove a file using the 7-pass US DoD method.
36 */
37
38int /* O - 0 on success, -1 on error */
39cupsdRemoveFile(const char *filename) /* I - File to remove */
40{
41#ifdef HAVE_REMOVEFILE
42 int ret; /* Return value */
43 removefile_state_t s; /* Remove state variable */
44
45
46 s = removefile_state_alloc();
47 ret = removefile(filename, s, REMOVEFILE_SECURE_7_PASS);
48
49 removefile_state_free(s);
50
51 return (ret);
52
53#else
54 int fd; /* File descriptor */
55 struct stat info; /* File information */
56 char buffer[512]; /* Data buffer */
57 int i; /* Looping var */
58
59
60 /*
61 * First open the file for writing in exclusive mode.
62 */
63
64 if ((fd = open(filename, O_WRONLY | O_EXCL)) < 0)
65 return (-1);
66
67 /*
68 * Delete the file now - it will still be around as long as the file is
69 * open...
70 */
71
72 unlink(filename);
73
74 /*
75 * Then get the file size...
76 */
77
78 if (fstat(fd, &info))
79 {
80 close(fd);
81 return (-1);
82 }
83
84 /*
85 * Overwrite the file 7 times with 0xF6, 0x00, 0xFF, random, 0x00, 0xFF,
86 * and more random data.
87 */
88
89 memset(buffer, 0xF6, sizeof(buffer));
90 if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
91 {
92 close(fd);
93 return (-1);
94 }
95
96 memset(buffer, 0x00, sizeof(buffer));
97 if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
98 {
99 close(fd);
100 return (-1);
101 }
102
103 memset(buffer, 0xFF, sizeof(buffer));
104 if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
105 {
106 close(fd);
107 return (-1);
108 }
109
110 for (i = 0; i < sizeof(buffer); i ++)
111 buffer[i] = rand();
112 if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
113 {
114 close(fd);
115 return (-1);
116 }
117
118 memset(buffer, 0x00, sizeof(buffer));
119 if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
120 {
121 close(fd);
122 return (-1);
123 }
124
125 memset(buffer, 0xFF, sizeof(buffer));
126 if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
127 {
128 close(fd);
129 return (-1);
130 }
131
132 for (i = 0; i < sizeof(buffer); i ++)
133 buffer[i] = rand();
134 if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
135 {
136 close(fd);
137 return (-1);
138 }
139
140 /*
141 * Whew! Close the file (which will lead to the actual deletion) and
142 * return success...
143 */
144
145 close(fd);
146 return (0);
147#endif /* HAVE_REMOVEFILE */
148}
149
150
151#ifndef HAVE_REMOVEFILE
152/*
153 * 'overwrite_data()' - Overwrite the data in a file.
154 */
155
156static int /* O - 0 on success, -1 on error */
157overwrite_data(int fd, /* I - File descriptor */
158 const char *buffer, /* I - Buffer to write */
159 int bufsize, /* I - Size of buffer */
160 int filesize) /* I - Size of file */
161{
162 int bytes; /* Bytes to write/written */
163
164
165 /*
166 * Start at the beginning of the file...
167 */
168
169 if (lseek(fd, 0, SEEK_SET) < 0)
170 return (-1);
171
172 /*
173 * Fill the file with the provided data...
174 */
175
176 while (filesize > 0)
177 {
178 if (filesize > bufsize)
179 bytes = bufsize;
180 else
181 bytes = filesize;
182
183 if ((bytes = write(fd, buffer, bytes)) < 0)
184 return (-1);
185
186 filesize -= bytes;
187 }
188
189 /*
190 * Force the changes to disk...
191 */
192
193 return (fsync(fd));
194}
195#endif /* HAVE_REMOVEFILE */
196
197
198#ifdef TEST
1f0275e3 199# define testmain main
cc0d019f 200int
1f0275e3 201testmain(void)
cc0d019f
MS
202{
203 FILE *fp;
204
205
206 fp = fopen("testfile.secure", "w");
207 fputs("Hello, World!\n", fp);
208 fputs("Now is the time for all good men to come to the aid of their "
209 "country.\n", fp);
210 fclose(fp);
211
212 if (cupsdRemoveFile("testfile.secure"))
213 {
214 printf("cupsdRemoveFile: FAIL (%s)\n", strerror(errno));
215 return (1);
216 }
217 else
218 {
219 puts("cupsdRemoveFile: PASS");
220 return (0);
221 }
222}
223#endif /* TEST */
224
225
226/*
227 * End of "$Id$".
228 */