1 /* Copyright 2003 Stefan Feuz, Lukas Meyer, Thomas Locher
2 * Copyright 2004,2006,2007,2009 Alain Knaff.
3 * This file is part of mtools.
4 *
5 * Mtools is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * Mtools is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Filename:
19 * mclasserase.c
20 *
21 * Original Creation Date:
22 * 05.III.2003
23 *
24 * Copyright:
25 * GPL
26 *
27 * Programmer:
28 * Stefan Feuz, Lukas Meyer, Thomas Locher
29 */
30
31 #include "sysincludes.h"
32 #include "msdos.h"
33 #include "mtools.h"
34 #include "vfat.h"
35 #include "mainloop.h"
36 #include "fsP.h"
37
38 #ifdef HAVE_GETOPT_H
39 #include <getopt.h>
40 #endif
41
42 #include "file.h"
43
44 #include <unistd.h>
45 #include <stdio.h>
46
47 /**
48 * Prints the Usage Message to STDOUT<br>
49 *
50 * @author stefan feuz<br>
51 * stefan.feuz@ruag.com
52 *
53 * @param n.a.
54 *
55 * @returns n.a.
56 *
57 */
58 static void usage(int ret) NORETURN;
usage(int ret)59 static void usage(int ret)
60 {
61 fprintf(stderr, "Mtools version %s, dated %s\n", mversion, mdate);
62 fprintf(stderr, "Usage: %s [-d] drive:\n", progname);
63 exit(ret);
64 }
65
66 /**
67 * Delete all files on a Drive.<br>
68 *
69 * @author Lukas Meyer<br>
70 * lukas.meyer@ruag.com
71 * @version 0.4, 11.12.2003
72 *
73 * @param drive the drive to erase
74 * @param debug 1: stop after each erase cycle, 0: normal mode
75 *
76 * @returns n.a.
77 *
78 */
79 static void do_mclasserase(char drive,int debug) NORETURN;
do_mclasserase(char drive,int debug)80 static void do_mclasserase(char drive,int debug)
81 {
82 struct device dev; /* Device information structure */
83 union bootsector boot;
84
85 int media; /* Just used to enter some in find_device */
86 char name[EXPAND_BUF];
87 Stream_t *Stream;
88 struct label_blk_t *labelBlock;
89
90 FILE * fDevice; /* Stores device's file descriptor */
91
92 char cCardType[12];
93
94 char drivel[3]; /* Stores the drive letter */
95
96
97 int i = 0;
98
99 /* FILE *forf; */
100
101 char dummy[2]; /* dummy input for debugging purposes.. */
102 int icount=0;
103 int iTotalErase = 0;
104
105 /* How many times we'll overwrite the media: */
106 #define CYCLES 3
107 unsigned char odat[CYCLES]; /* Data for each overwrite procedure */
108
109 /* Creating values for overwrite */
110 odat[0]=0xff;
111 odat[1]=0x00;
112 odat[2]=0xff;
113
114
115 if (debug == 1)
116 printf("cycles: %i, odats: %i,%i,%i\n",CYCLES,odat[0],odat[1],odat[2]);
117
118
119
120 /* Reading parameters from card. Exit with -1 if failed. */
121 if(! (Stream = find_device(drive, O_RDONLY, &dev, &boot,
122 name, &media, 0, NULL)))
123 exit(1);
124
125 FREE(&Stream);
126
127 /* Determine the FAT - type */
128 #if 0
129 if(WORD(fatlen)) {
130 labelBlock = &bbelBlock = &boot->ext.old.labelBlock;
131 } else {
132 labelBlock = &boot->ext.fat32.labelBlock;
133 }
134 #endif
135
136 /* we use only FAT12/16 ...*/
137 labelBlock = &boot.boot.ext.old.labelBlock;
138
139 /* store card type */
140 sprintf(cCardType, "%11.11s", labelBlock->label);
141
142 if (debug == 1)
143 {
144 printf("Using Device: %s\n",name);
145 printf("Card-Type detected: %s\n",cCardType);
146 }
147
148 /* Forming cat command to overwrite the medias content. */
149 sprintf( drivel, "%c:", ch_tolower(drive) );
150
151 #if 0
152 media_sectors = dev.tracks * dev.sectors;
153 sector_size = WORD(secsiz) * dev.heads;
154
155
156 printf(mcat);
157 printf("\n%d\n", media_sectors);
158 printf("%d\n", sector_size);
159 #endif
160
161 /*
162 * Overwrite device
163 */
164 for( i=0; i < CYCLES; i++){
165
166 if (debug==1)
167 {
168 printf("Erase Cycle %i, writing data: 0x%2.2x...\n",i+1,odat[i]);
169 }
170
171 fDevice = fopen(name,"ab+");
172
173 if (fDevice == 0)
174 {
175 perror("Error opening device");
176 exit(-1);
177 }
178
179
180 if (debug==1)
181 {
182 printf("Open successful...\n");
183 printf("Flushing device after 32 kBytes of data...\n");
184 printf("Erasing:");
185 fflush( stdout );
186 }
187
188 /* iTotalErase = 0; */
189
190 /*
191 * overwrite the whole device
192 */
193 while ((feof(fDevice)==0) && (ferror(fDevice)==0))
194 {
195
196 fputc(odat[i],fDevice);
197
198 icount++;
199 if (icount > (32 * 1024))
200 {
201 /* flush device every 32KB of data...*/
202 fflush( fDevice );
203
204 iTotalErase += icount;
205 if (debug == 1)
206 {
207 printf(".");
208 fflush( stdout );
209 }
210 icount=0;
211 }
212 }
213
214 if (debug==1)
215 {
216 printf("\nPress <ENTER> to continue\n");
217 printf("Press <x> and <ENTER> to abort\n");
218
219 if(scanf("%c",dummy) < 1)
220 printf("Input error\n");
221 fflush( stdin );
222
223 if (strcmp(dummy,"x") == 0)
224 {
225 printf("exiting.\n");
226 exit(0);
227 }
228 }
229
230 fclose(fDevice);
231
232 }
233
234
235 /*
236 * Format device using shell script
237 */
238 if (debug == 0)
239 {
240 /* redirect STDERR and STDOUT to the black hole... */
241 if (dup2(open("/dev/null", O_WRONLY), STDERR_FILENO) != STDERR_FILENO)
242 printf("Error with dup2() stdout\n");
243 if (dup2(open("/dev/null", O_WRONLY), STDOUT_FILENO) != STDOUT_FILENO)
244 printf("Error with dup2() stdout\n");
245 }
246
247 if (debug == 1)
248 printf("Calling amuFormat.sh with args: %s,%s\n",cCardType,drivel);
249
250 execlp("amuFormat.sh","",cCardType,drivel,NULL);
251
252 /* we never come back...(we shouldn't come back ...) */
253 exit(-1);
254
255 }
256
257
258 /**
259 * Total Erase of Data on a Disk. After using mclasserase there won't
260 * be ANY bits of old files on the disk.<br>
261 * </b>
262 * @author stefan feuz<br>
263 * thomas locher<br>
264 * stefan.feuz@ruag.com
265 * thomas.locher@ruag.com
266 * @version 0.3, 02.12.2003
267 *
268 * @param argc generated automatically by operating systems
269 * @param **argv1 generated automatically by operating systems
270 * @param type generated automatically by operating systems
271 *
272 * @param -d stop after each erase cycle, for testing purposes
273 *
274 * @returns int 0 if all is well done<br>
275 * int -1 if there is something wrong
276 *
277 * @info mclasserase [-p tempFilePath] [-d] drive:
278 *
279 *
280 */
281 void mclasserase(int argc, char **argv, int type UNUSEDP) NORETURN;
mclasserase(int argc,char ** argv,int type UNUSEDP)282 void mclasserase(int argc, char **argv, int type UNUSEDP)
283 {
284 /* declaration of all variables */
285 int c;
286 int debug=0;
287 /* char* tempFilePath=NULL; */
288 char drive='a';
289
290 extern int optind;
291
292 destroy_privs();
293
294 /* check and read command line arguments */
295 #ifdef DEBUG
296 printf("mclasserase: argc = %i\n",argc);
297 #endif
298 /* check num of arguments */
299 if(helpFlag(argc, argv))
300 usage(0);
301 if ( (argc != 2) & (argc != 3) & (argc != 4))
302 { /* wrong num of arguments */
303 printf ("mclasserase: wrong num of args\n");
304 usage(1);
305 }
306 else
307 { /* correct num of arguments */
308 while ((c = getopt(argc, argv, "+p:dh")) != EOF)
309 {
310 switch (c)
311 {
312
313 case 'd':
314
315 printf("=============\n");
316 printf("Debug Mode...\n");
317 printf("=============\n");
318 debug = 1;
319 break;
320 case 'p':
321 printf("option -p not implemented yet\n");
322 break;
323 case 'h':
324 usage(0);
325 case '?':
326 usage(1);
327 default:
328 break;
329 }
330 }
331 #ifdef DEBUG
332 printf("mclasserase: optind = %i\n",optind);
333 /* look for the drive to erase */
334 printf("mclasserase: searching drive\n");
335 #endif
336 for(; optind < argc; optind++)
337 {
338 if(!argv[optind][0] || argv[optind][1] != ':')
339 {
340 usage(1);
341 }
342 drive = ch_toupper(argv[optind][0]);
343 }
344 }
345 #ifdef DEBUG
346 printf("mclasserase: found drive %c\n", drive);
347 #endif
348 /* remove all data on drive, you never come back if drive does
349 * not exist */
350
351 do_mclasserase(drive,debug);
352 }
353