cmd.exe: Add move support for wildcards and directories.
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 7e79aeb..832da83 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -715,47 +715,89 @@
* WCMD_move
*
* Move a file, directory tree or wildcarded set of files.
- * FIXME: Needs input and output files to be fully specified.
*/
void WCMD_move (void) {
- int status;
- char outpath[MAX_PATH], inpath[MAX_PATH], *infile;
+ int status;
WIN32_FIND_DATA fd;
- HANDLE hff;
+ HANDLE hff;
+ char input[MAX_PATH];
+ char output[MAX_PATH];
+ char drive[10];
+ char dir[MAX_PATH];
+ char fname[MAX_PATH];
+ char ext[MAX_PATH];
if (param1[0] == 0x00) {
WCMD_output ("Argument missing\n");
return;
}
- if ((strchr(param1,'*') != NULL) || (strchr(param1,'%') != NULL)) {
- WCMD_output ("Wildcards not yet supported\n");
- return;
- }
-
/* If no destination supplied, assume current directory */
if (param2[0] == 0x00) {
strcpy(param2, ".");
}
/* If 2nd parm is directory, then use original filename */
- GetFullPathName (param2, sizeof(outpath), outpath, NULL);
- if (outpath[strlen(outpath) - 1] == '\\')
- outpath[strlen(outpath) - 1] = '\0';
- hff = FindFirstFile (outpath, &fd);
- if (hff != INVALID_HANDLE_VALUE) {
- if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- GetFullPathName (param1, sizeof(inpath), inpath, &infile);
- strcat (outpath, "\\");
- strcat (outpath, infile);
- }
- FindClose (hff);
- }
+ /* Convert partial path to full path */
+ GetFullPathName (param1, sizeof(input), input, NULL);
+ GetFullPathName (param2, sizeof(output), output, NULL);
+ WINE_TRACE("Move from '%s'('%s') to '%s'\n", input, param1, output);
- status = MoveFile (param1, outpath);
- if (!status) WCMD_print_error ();
+ /* Split into components */
+ WCMD_splitpath(input, drive, dir, fname, ext);
+
+ hff = FindFirstFile (input, &fd);
+ while (hff != INVALID_HANDLE_VALUE) {
+ char dest[MAX_PATH];
+ char src[MAX_PATH];
+ DWORD attribs;
+
+ WINE_TRACE("Processing file '%s'\n", fd.cFileName);
+
+ /* Build src & dest name */
+ strcpy(src, drive);
+ strcat(src, dir);
+
+ /* See if dest is an existing directory */
+ attribs = GetFileAttributes(output);
+ if (attribs != INVALID_FILE_ATTRIBUTES &&
+ (attribs & FILE_ATTRIBUTE_DIRECTORY)) {
+ strcpy(dest, output);
+ strcat(dest, "\\");
+ strcat(dest, fd.cFileName);
+ } else {
+ strcpy(dest, output);
+ }
+
+ strcat(src, fd.cFileName);
+
+ WINE_TRACE("Source '%s'\n", src);
+ WINE_TRACE("Dest '%s'\n", dest);
+
+ /* Check if file is read only, otherwise move it */
+ attribs = GetFileAttributesA(src);
+ if ((attribs != INVALID_FILE_ATTRIBUTES) &&
+ (attribs & FILE_ATTRIBUTE_READONLY)) {
+ SetLastError(ERROR_ACCESS_DENIED);
+ status = 0;
+ } else {
+ status = MoveFile (src, dest);
+ }
+
+ if (!status) {
+ WCMD_print_error ();
+ errorlevel = 1;
+ }
+
+ /* Step on to next match */
+ if (FindNextFile(hff, &fd) == 0) {
+ FindClose(hff);
+ hff = INVALID_HANDLE_VALUE;
+ break;
+ }
+ }
}
/****************************************************************************
@@ -838,7 +880,6 @@
* WCMD_rename
*
* Rename a file.
- * FIXME: Needs input and output files to be fully specified.
*/
void WCMD_rename (void) {