Commit 32ea7d1f authored by Dan Kegel's avatar Dan Kegel Committed by Alexandre Julliard

cmd: WCMD_delete: fix /s for dirnames containing spaces, add test.

parent 2bd19a89
......@@ -621,58 +621,35 @@ static BOOL WCMD_delete_confirm_wildcard(WCHAR *filename, BOOL *pPrompted) {
return TRUE;
}
/****************************************************************************
* WCMD_delete
*
* Delete a file or wildcarded set.
*
* Note on /A:
* - Testing shows /A is repeatable, eg. /a-r /ar matches all files
* - Each set is a pattern, eg /ahr /as-r means
* readonly+hidden OR nonreadonly system files
* - The '-' applies to a single field, ie /a:-hr means read only
* non-hidden files
/* Helper function for WCMD_delete().
* Deletes a single file, directory, or wildcard.
* If /S was given, does it recursively.
* Returns TRUE if a file was deleted.
*/
static BOOL WCMD_delete_one (WCHAR *thisArg) {
BOOL WCMD_delete (WCHAR *command, BOOL expectDir) {
int argno = 0;
int argsProcessed = 0;
WCHAR *argN = command;
BOOL foundAny = FALSE;
static const WCHAR parmP[] = {'/','P','\0'};
static const WCHAR parmS[] = {'/','S','\0'};
static const WCHAR parmF[] = {'/','F','\0'};
DWORD wanted_attrs;
DWORD unwanted_attrs;
WCMD_delete_parse_attributes(&wanted_attrs, &unwanted_attrs);
/* If not recursing, clear error flag */
if (expectDir) errorlevel = 0;
/* Loop through all args */
while (argN) {
WCHAR *thisArg = WCMD_parameter (command, argno++, &argN);
BOOL found = FALSE;
WCHAR argCopy[MAX_PATH];
if (argN && argN[0] != '/') {
WIN32_FIND_DATAW fd;
HANDLE hff;
WCHAR fpath[MAX_PATH];
WCHAR *p;
BOOL handleParm = TRUE;
BOOL found = FALSE;
WCMD_delete_parse_attributes(&wanted_attrs, &unwanted_attrs);
strcpyW(argCopy, thisArg);
WINE_TRACE("del: Processing arg %s (quals:%s)\n",
wine_dbgstr_w(argCopy), wine_dbgstr_w(quals));
argsProcessed++;
if (!WCMD_delete_confirm_wildcard(argCopy, &found)) {
/* Skip this arg if user declines to delete *.* */
continue;
return FALSE;
}
/* First, try to delete in the current directory */
......@@ -684,8 +661,11 @@ BOOL WCMD_delete (WCHAR *command, BOOL expectDir) {
}
/* Support del <dirname> by just deleting all files dirname\* */
if (handleParm && (strchrW(argCopy,'*') == NULL) && (strchrW(argCopy,'?') == NULL)
&& (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (handleParm
&& (strchrW(argCopy,'*') == NULL)
&& (strchrW(argCopy,'?') == NULL)
&& (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
WCHAR modifiedParm[MAX_PATH];
static const WCHAR slashStar[] = {'\\','*','\0'};
......@@ -693,7 +673,7 @@ BOOL WCMD_delete (WCHAR *command, BOOL expectDir) {
strcatW(modifiedParm, slashStar);
FindClose(hff);
found = TRUE;
WCMD_delete(modifiedParm, FALSE);
WCMD_delete_one(modifiedParm);
} else if (handleParm) {
......@@ -809,7 +789,7 @@ BOOL WCMD_delete (WCHAR *command, BOOL expectDir) {
DIRECTORY_STACK *tempDir;
tempDir = allDirs->next;
found |= WCMD_delete (allDirs->dirName, FALSE);
found |= WCMD_delete_one (allDirs->dirName);
HeapFree(GetProcessHeap(),0,allDirs->dirName);
HeapFree(GetProcessHeap(),0,allDirs);
......@@ -817,22 +797,54 @@ BOOL WCMD_delete (WCHAR *command, BOOL expectDir) {
}
}
}
/* Keep running total to see if any found, and if not recursing
issue error message */
if (expectDir) {
return found;
}
/****************************************************************************
* WCMD_delete
*
* Delete a file or wildcarded set.
*
* Note on /A:
* - Testing shows /A is repeatable, eg. /a-r /ar matches all files
* - Each set is a pattern, eg /ahr /as-r means
* readonly+hidden OR nonreadonly system files
* - The '-' applies to a single field, ie /a:-hr means read only
* non-hidden files
*/
BOOL WCMD_delete (WCHAR *command) {
int argno;
WCHAR *argN;
BOOL argsProcessed = FALSE;
BOOL foundAny = FALSE;
errorlevel = 0;
for (argno=0; ; argno++) {
BOOL found;
WCHAR *thisArg;
argN = NULL;
thisArg = WCMD_parameter (command, argno, &argN);
if (!argN)
break; /* no more parameters */
if (argN[0] == '/')
continue; /* skip options */
argsProcessed = TRUE;
found = WCMD_delete_one(thisArg);
if (!found) {
errorlevel = 1;
WCMD_output (WCMD_LoadMessage(WCMD_FILENOTFOUND), argCopy);
}
WCMD_output (WCMD_LoadMessage(WCMD_FILENOTFOUND), thisArg);
}
foundAny |= found;
}
}
/* Handle no valid args */
if (argsProcessed == 0) {
if (!argsProcessed)
WCMD_output (WCMD_LoadMessage(WCMD_NOARG));
}
return foundAny;
}
......
......@@ -106,6 +106,26 @@ for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
cd ..
rmdir del_q_dir
echo ------------ Testing del /s --------------
mkdir "foo bar"
cd "foo bar"
echo hi > file1.dat
echo there > file2.dat
echo bub > file3.dat
echo bye > "file with spaces.dat"
cd ..
del /s file1.dat > nul
del file2.dat /s > nul
del "file3.dat" /s > nul
del "file with spaces.dat" /s > nul
cd "foo bar"
for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
if exist "file with spaces.dat" del "file with spaces.dat"
cd ..
rmdir "foo bar"
echo -----------Testing Errorlevel-----------
rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
rem See http://www.robvanderwoude.com/exit.php
......
......@@ -85,6 +85,7 @@ r.test not found after delete, good
------------ Testing del /q --------------
del /q * succeeded on file1
del /q * succeeded on file2.dat
------------ Testing del /s --------------
-----------Testing Errorlevel-----------
1
errorlevel just right, good
......
......@@ -57,7 +57,7 @@ void WCMD_clear_screen (void);
void WCMD_color (void);
void WCMD_copy (void);
void WCMD_create_dir (void);
BOOL WCMD_delete (WCHAR *, BOOL);
BOOL WCMD_delete (WCHAR *);
void WCMD_directory (WCHAR *);
void WCMD_echo (const WCHAR *);
void WCMD_endlocal (void);
......
......@@ -1447,7 +1447,7 @@ void WCMD_execute (WCHAR *command, WCHAR *redirects,
break;
case WCMD_DEL:
case WCMD_ERASE:
WCMD_delete (p, TRUE);
WCMD_delete (p);
break;
case WCMD_DIR:
WCMD_directory (p);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment