xref: /aosp_15_r20/external/mtools/mdel.c (revision d5c9a868b113e0ec0db2f27bc2ce8a253e77c4b0)
1*d5c9a868SElliott Hughes /*  Copyright 1986-1992 Emmet P. Gray.
2*d5c9a868SElliott Hughes  *  Copyright 1996-2002,2005,2008,2009 Alain Knaff.
3*d5c9a868SElliott Hughes  *  This file is part of mtools.
4*d5c9a868SElliott Hughes  *
5*d5c9a868SElliott Hughes  *  Mtools is free software: you can redistribute it and/or modify
6*d5c9a868SElliott Hughes  *  it under the terms of the GNU General Public License as published by
7*d5c9a868SElliott Hughes  *  the Free Software Foundation, either version 3 of the License, or
8*d5c9a868SElliott Hughes  *  (at your option) any later version.
9*d5c9a868SElliott Hughes  *
10*d5c9a868SElliott Hughes  *  Mtools is distributed in the hope that it will be useful,
11*d5c9a868SElliott Hughes  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12*d5c9a868SElliott Hughes  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*d5c9a868SElliott Hughes  *  GNU General Public License for more details.
14*d5c9a868SElliott Hughes  *
15*d5c9a868SElliott Hughes  *  You should have received a copy of the GNU General Public License
16*d5c9a868SElliott Hughes  *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
17*d5c9a868SElliott Hughes  *
18*d5c9a868SElliott Hughes  * mdel.c
19*d5c9a868SElliott Hughes  * Delete an MSDOS file
20*d5c9a868SElliott Hughes  *
21*d5c9a868SElliott Hughes  */
22*d5c9a868SElliott Hughes 
23*d5c9a868SElliott Hughes #include "sysincludes.h"
24*d5c9a868SElliott Hughes #include "msdos.h"
25*d5c9a868SElliott Hughes #include "mtools.h"
26*d5c9a868SElliott Hughes #include "stream.h"
27*d5c9a868SElliott Hughes #include "mainloop.h"
28*d5c9a868SElliott Hughes #include "fs.h"
29*d5c9a868SElliott Hughes #include "file.h"
30*d5c9a868SElliott Hughes #include "file_name.h"
31*d5c9a868SElliott Hughes 
32*d5c9a868SElliott Hughes typedef struct Arg_t {
33*d5c9a868SElliott Hughes 	int deltype;
34*d5c9a868SElliott Hughes 	int verbose;
35*d5c9a868SElliott Hughes } Arg_t;
36*d5c9a868SElliott Hughes 
37*d5c9a868SElliott Hughes /**
38*d5c9a868SElliott Hughes  * Wiped the given entry
39*d5c9a868SElliott Hughes  */
wipeEntry(direntry_t * entry)40*d5c9a868SElliott Hughes void wipeEntry(direntry_t *entry)
41*d5c9a868SElliott Hughes {
42*d5c9a868SElliott Hughes 	direntry_t longNameEntry;
43*d5c9a868SElliott Hughes 	int i;
44*d5c9a868SElliott Hughes 	initializeDirentry(&longNameEntry, entry->Dir);
45*d5c9a868SElliott Hughes 	for(i=entry->beginSlot; i< entry->endSlot; i++) {
46*d5c9a868SElliott Hughes 	    int error;
47*d5c9a868SElliott Hughes 	    longNameEntry.entry=i;
48*d5c9a868SElliott Hughes 	    dir_read(&longNameEntry, &error);
49*d5c9a868SElliott Hughes 	    if(error)
50*d5c9a868SElliott Hughes 		break;
51*d5c9a868SElliott Hughes 	    longNameEntry.dir.name[0] = (char) DELMARK;
52*d5c9a868SElliott Hughes 	    dir_write(&longNameEntry);
53*d5c9a868SElliott Hughes 	}
54*d5c9a868SElliott Hughes 	entry->dir.name[0] = (char) DELMARK;
55*d5c9a868SElliott Hughes 	dir_write(entry);
56*d5c9a868SElliott Hughes }
57*d5c9a868SElliott Hughes 
del_entry(direntry_t * entry,MainParam_t * mp)58*d5c9a868SElliott Hughes static int del_entry(direntry_t *entry, MainParam_t *mp)
59*d5c9a868SElliott Hughes {
60*d5c9a868SElliott Hughes 	Arg_t *arg=(Arg_t *) mp->arg;
61*d5c9a868SElliott Hughes 
62*d5c9a868SElliott Hughes 	if(got_signal)
63*d5c9a868SElliott Hughes 		return ERROR_ONE;
64*d5c9a868SElliott Hughes 
65*d5c9a868SElliott Hughes 	if(entry->entry == -3) {
66*d5c9a868SElliott Hughes 		fprintf(stderr, "Cannot remove root directory\n");
67*d5c9a868SElliott Hughes 		return ERROR_ONE;
68*d5c9a868SElliott Hughes 	}
69*d5c9a868SElliott Hughes 
70*d5c9a868SElliott Hughes 	if (arg->verbose) {
71*d5c9a868SElliott Hughes 		fprintf(stderr,"Removing ");
72*d5c9a868SElliott Hughes 		fprintPwd(stderr, entry,0);
73*d5c9a868SElliott Hughes 		fputc('\n', stderr);
74*d5c9a868SElliott Hughes 	}
75*d5c9a868SElliott Hughes 
76*d5c9a868SElliott Hughes 	if (entry->dir.attr & (ATTR_READONLY | ATTR_SYSTEM)) {
77*d5c9a868SElliott Hughes 		char tmp[4*MAX_VNAMELEN+1];
78*d5c9a868SElliott Hughes 		WCHAR_TO_NATIVE(entry->name,tmp,MAX_VNAMELEN);
79*d5c9a868SElliott Hughes 		if (ask_confirmation("%s: \"%s\" is read only, erase anyway (y/n) ? ",
80*d5c9a868SElliott Hughes 				     progname, tmp))
81*d5c9a868SElliott Hughes 			return ERROR_ONE;
82*d5c9a868SElliott Hughes 	}
83*d5c9a868SElliott Hughes 	if (fatFreeWithDirentry(entry))
84*d5c9a868SElliott Hughes 		return ERROR_ONE;
85*d5c9a868SElliott Hughes 
86*d5c9a868SElliott Hughes 	wipeEntry(entry);
87*d5c9a868SElliott Hughes 	return GOT_ONE;
88*d5c9a868SElliott Hughes }
89*d5c9a868SElliott Hughes 
del_file(direntry_t * entry,MainParam_t * mp)90*d5c9a868SElliott Hughes static int del_file(direntry_t *entry, MainParam_t *mp)
91*d5c9a868SElliott Hughes {
92*d5c9a868SElliott Hughes 	char shortname[13];
93*d5c9a868SElliott Hughes 	direntry_t subEntry;
94*d5c9a868SElliott Hughes 	Stream_t *SubDir;
95*d5c9a868SElliott Hughes 	Arg_t *arg = (Arg_t *) mp->arg;
96*d5c9a868SElliott Hughes 	MainParam_t sonmp;
97*d5c9a868SElliott Hughes 	int ret;
98*d5c9a868SElliott Hughes 	int r;
99*d5c9a868SElliott Hughes 
100*d5c9a868SElliott Hughes 	sonmp = *mp;
101*d5c9a868SElliott Hughes 	sonmp.arg = mp->arg;
102*d5c9a868SElliott Hughes 
103*d5c9a868SElliott Hughes 	r = 0;
104*d5c9a868SElliott Hughes 	if (IS_DIR(entry)){
105*d5c9a868SElliott Hughes 		/* a directory */
106*d5c9a868SElliott Hughes 		SubDir = OpenFileByDirentry(entry);
107*d5c9a868SElliott Hughes 		initializeDirentry(&subEntry, SubDir);
108*d5c9a868SElliott Hughes 		ret = 0;
109*d5c9a868SElliott Hughes 		while((r=vfat_lookup(&subEntry, "*", 1,
110*d5c9a868SElliott Hughes 				     ACCEPT_DIR | ACCEPT_PLAIN,
111*d5c9a868SElliott Hughes 				     shortname, sizeof(shortname),
112*d5c9a868SElliott Hughes 				     NULL, 0)) == 0 ){
113*d5c9a868SElliott Hughes 			if(shortname[0] != DELMARK &&
114*d5c9a868SElliott Hughes 			   shortname[0] &&
115*d5c9a868SElliott Hughes 			   shortname[0] != '.' ){
116*d5c9a868SElliott Hughes 				if(arg->deltype != 2){
117*d5c9a868SElliott Hughes 					fprintf(stderr,
118*d5c9a868SElliott Hughes 						"Directory ");
119*d5c9a868SElliott Hughes 					fprintPwd(stderr, entry,0);
120*d5c9a868SElliott Hughes 					fprintf(stderr," non empty\n");
121*d5c9a868SElliott Hughes 					ret = ERROR_ONE;
122*d5c9a868SElliott Hughes 					break;
123*d5c9a868SElliott Hughes 				}
124*d5c9a868SElliott Hughes 				if(got_signal) {
125*d5c9a868SElliott Hughes 					ret = ERROR_ONE;
126*d5c9a868SElliott Hughes 					break;
127*d5c9a868SElliott Hughes 				}
128*d5c9a868SElliott Hughes 				ret = del_file(&subEntry, &sonmp);
129*d5c9a868SElliott Hughes 				if( ret & ERROR_ONE)
130*d5c9a868SElliott Hughes 					break;
131*d5c9a868SElliott Hughes 				ret = 0;
132*d5c9a868SElliott Hughes 			}
133*d5c9a868SElliott Hughes 		}
134*d5c9a868SElliott Hughes 		FREE(&SubDir);
135*d5c9a868SElliott Hughes 		if (r == -2)
136*d5c9a868SElliott Hughes 			return ERROR_ONE;
137*d5c9a868SElliott Hughes 		if(ret)
138*d5c9a868SElliott Hughes 			return ret;
139*d5c9a868SElliott Hughes 	}
140*d5c9a868SElliott Hughes 	return del_entry(entry, mp);
141*d5c9a868SElliott Hughes }
142*d5c9a868SElliott Hughes 
143*d5c9a868SElliott Hughes static void usage(int ret) NORETURN;
usage(int ret)144*d5c9a868SElliott Hughes static void usage(int ret)
145*d5c9a868SElliott Hughes {
146*d5c9a868SElliott Hughes 	fprintf(stderr,
147*d5c9a868SElliott Hughes 		"Mtools version %s, dated %s\n", mversion, mdate);
148*d5c9a868SElliott Hughes 	fprintf(stderr,
149*d5c9a868SElliott Hughes 		"Usage: %s [-v] msdosfile [msdosfiles...]\n", progname);
150*d5c9a868SElliott Hughes 	exit(ret);
151*d5c9a868SElliott Hughes }
152*d5c9a868SElliott Hughes 
153*d5c9a868SElliott Hughes void mdel(int argc, char **argv, int deltype) NORETURN;
mdel(int argc,char ** argv,int deltype)154*d5c9a868SElliott Hughes void mdel(int argc, char **argv, int deltype)
155*d5c9a868SElliott Hughes {
156*d5c9a868SElliott Hughes 	Arg_t arg;
157*d5c9a868SElliott Hughes 	MainParam_t mp;
158*d5c9a868SElliott Hughes 	int c,i;
159*d5c9a868SElliott Hughes 
160*d5c9a868SElliott Hughes 	arg.verbose = 0;
161*d5c9a868SElliott Hughes 	if(helpFlag(argc, argv))
162*d5c9a868SElliott Hughes 		usage(0);
163*d5c9a868SElliott Hughes 	while ((c = getopt(argc, argv, "i:vh")) != EOF) {
164*d5c9a868SElliott Hughes 		switch (c) {
165*d5c9a868SElliott Hughes 			case 'i':
166*d5c9a868SElliott Hughes 				set_cmd_line_image(optarg);
167*d5c9a868SElliott Hughes 				break;
168*d5c9a868SElliott Hughes 			case 'v':
169*d5c9a868SElliott Hughes 				arg.verbose = 1;
170*d5c9a868SElliott Hughes 				break;
171*d5c9a868SElliott Hughes 			case 'h':
172*d5c9a868SElliott Hughes 				usage(0);
173*d5c9a868SElliott Hughes 			default:
174*d5c9a868SElliott Hughes 				usage(1);
175*d5c9a868SElliott Hughes 		}
176*d5c9a868SElliott Hughes 	}
177*d5c9a868SElliott Hughes 
178*d5c9a868SElliott Hughes 	if(argc == optind)
179*d5c9a868SElliott Hughes 		usage(1);
180*d5c9a868SElliott Hughes 
181*d5c9a868SElliott Hughes 	init_mp(&mp);
182*d5c9a868SElliott Hughes 	mp.callback = del_file;
183*d5c9a868SElliott Hughes 	mp.arg = (void *) &arg;
184*d5c9a868SElliott Hughes 	mp.openflags = O_RDWR;
185*d5c9a868SElliott Hughes 	arg.deltype = deltype;
186*d5c9a868SElliott Hughes 	switch(deltype){
187*d5c9a868SElliott Hughes 	case 0:
188*d5c9a868SElliott Hughes 		mp.lookupflags = ACCEPT_PLAIN; /* mdel */
189*d5c9a868SElliott Hughes 		break;
190*d5c9a868SElliott Hughes 	case 1:
191*d5c9a868SElliott Hughes 		mp.lookupflags = ACCEPT_DIR; /* mrd */
192*d5c9a868SElliott Hughes 		break;
193*d5c9a868SElliott Hughes 	case 2:
194*d5c9a868SElliott Hughes 		mp.lookupflags = ACCEPT_DIR | ACCEPT_PLAIN; /* mdeltree */
195*d5c9a868SElliott Hughes 		break;
196*d5c9a868SElliott Hughes 	}
197*d5c9a868SElliott Hughes 	mp.lookupflags |= NO_DOTS;
198*d5c9a868SElliott Hughes 	for(i=optind;i<argc;i++) {
199*d5c9a868SElliott Hughes 		size_t b, l;
200*d5c9a868SElliott Hughes 		if(argv[i][0] && argv[i][1] == ':')
201*d5c9a868SElliott Hughes 			b = 2;
202*d5c9a868SElliott Hughes 		else
203*d5c9a868SElliott Hughes 			b = 0;
204*d5c9a868SElliott Hughes 		l = strlen(argv[i]+b);
205*d5c9a868SElliott Hughes 		if(l > 1 && argv[i][b+l-1] == '/')
206*d5c9a868SElliott Hughes 			argv[i][b+l-1] = '\0';
207*d5c9a868SElliott Hughes 	}
208*d5c9a868SElliott Hughes 
209*d5c9a868SElliott Hughes 	exit(main_loop(&mp, argv + optind, argc - optind));
210*d5c9a868SElliott Hughes }
211