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