• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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