Skip to content

Commit 095f651

Browse files
committed
enable recursive remove dir (rd /s)
1 parent 327a24a commit 095f651

File tree

2 files changed

+125
-5
lines changed

2 files changed

+125
-5
lines changed

cmd/rmdir.c

Lines changed: 124 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,139 @@
44

55
#include "../config.h"
66

7+
#include <assert.h>
8+
#include <dos.h>
79
#include <io.h>
10+
#include <stdio.h>
11+
#include <stdlib.h>
12+
#include <string.h>
13+
14+
#include "suppl.h"
15+
#include "dfn.h"
816

917
#include "../include/command.h"
1018
#include "../include/misc.h"
1119
#include "../include/lfnfuncs.h"
20+
#include "../err_fcts.h"
21+
#include "../strings.h"
1222

13-
int recursive_rmdir(const char * path, int optRecursiveMode, int optQuiet)
23+
#ifdef FEATURE_LONG_FILENAMES
24+
#define abspath( x, y ) abspath( getshortfilename( x ), y )
25+
#endif
26+
27+
/* recursively delete subdirs and files */
28+
int rmdir_withfiles(char * path, int maxlen)
1429
{
15-
/* optQuiet effects parsing showing errors, but no effect on recursive call */
16-
(void) optQuiet;
30+
struct dos_ffblk f;
31+
int len = strlen(path); /* Warning: we assume path is a buffer is large enough for longest file path */
32+
char *p = path+len;
33+
34+
/* ensure ends with \ */
35+
if (p[-1] != '\\')
36+
*p++ = '\\';
37+
*p = '\0';
1738

39+
dprintf(("rmdir(%s)\n", path));
40+
41+
/* cycle through removing directories first */
42+
stpcpy(p, "*.*");
43+
if (!dos_findfirst(path, &f, FA_DIREC)) {
44+
int ret = 0;
45+
do {
46+
/* skip . and .. directory entries */
47+
if ((strcmp(f.ff_name, ".")==0) ||
48+
(strcmp(f.ff_name, "..")==0))
49+
continue;
50+
51+
if (f.ff_attrib & FA_DIREC) {
52+
dprintf(("name=%s\n", f.ff_name));
53+
/* avoid overflowing our buffer */
54+
if((len + strlen(f.ff_name)) > maxlen) {
55+
error_filename_too_long(p);
56+
return E_Other;
57+
}
58+
59+
strcpy(p, f.ff_name); /* Make the full path */
60+
/* recursively delete subdirectory */
61+
ret = rmdir_withfiles(path, maxlen);
62+
}
63+
} while (!ret && (dos_findnext(&f) == 0));
64+
dos_findclose(&f);
65+
/* return early on error */
66+
if (ret) return ret;
67+
}
68+
69+
/* remove any files in current directory */
70+
stpcpy(p, "*.*");
71+
if (!dos_findfirst(path, &f, FA_NORMAL)) {
72+
do {
73+
/* avoid overflowing our buffer */
74+
if((len + strlen(f.ff_name)) > maxlen) {
75+
error_filename_too_long(p);
76+
return E_Other;
77+
}
78+
79+
strcpy(p, f.ff_name); /* Make the full path */
80+
dprintf(("deleting [%s]\n", path));
81+
/* try to delete the file */
82+
if(unlink(path) != 0)
83+
myperror(path); /* notify the user */
84+
} while (dos_findnext(&f) == 0);
85+
dos_findclose(&f);
86+
}
87+
88+
/* finally actually remove the directory */
89+
*p = '\0';
90+
return rmdir(path);
91+
}
92+
93+
int recursive_rmdir(const char * path, int optRecursiveMode, int optQuiet)
94+
{
1895
if (optRecursiveMode) {
19-
return 0;
96+
struct dos_ffblk f;
97+
char fullname[MAXPATH + sizeof(f.ff_name) + 2], *p;
98+
int len;
99+
/* Get the pattern fully-qualified */
100+
/* Note: An absolute path always contains:
101+
A:\\
102+
--> It's always three bytes long at minimum
103+
and always contains a backslash */
104+
p = abspath(path, 1);
105+
if(!p)
106+
return E_Other;
107+
assert(strlen(p) >= 3);
108+
109+
if((len = strlen(p)) >= MAXPATH) {
110+
error_filename_too_long(p);
111+
free(p);
112+
return E_Other;
113+
}
114+
strcpy(fullname, p);
115+
free(p);
116+
p = fullname + len;
117+
118+
/* validate path exists and is a directory */
119+
if(!(dfnstat(fullname) & DFN_DIRECTORY)) {
120+
/* not a directory */
121+
return E_Other;
122+
}
123+
124+
/* ensure ends with \ */
125+
if (p[-1] != '\\')
126+
*p++ = '\\';
127+
*p = 0;
128+
129+
/* prompt user if they are sure, regardless if files or not */
130+
if (!optQuiet) {
131+
int r;
132+
r = userprompt(PROMPT_DELETE_ALL, fullname); /* Are you sure? TODO fix me */
133+
134+
if (r != 1) {
135+
return E_Other;
136+
}
137+
}
138+
139+
return rmdir_withfiles(fullname, sizeof(fullname));
20140
} else {
21141
return rmdir(path);
22142
}

lib/mk_rddir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
static int optRecursiveMode, optQuiet;
1818

19-
/*#define COMMAND_EXTENSIONS*/
19+
#define COMMAND_EXTENSIONS
2020
#ifdef COMMAND_EXTENSIONS
2121
optScanFct(opt_md_rd)
2222
{

0 commit comments

Comments
 (0)