Jason Edmeades : cmd.exe: Add move support for wildcards and directories.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Apr 12 10:00:03 CDT 2007


Module: wine
Branch: master
Commit: d0a6fe101acd2c88659737e83fdf650b002331f7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d0a6fe101acd2c88659737e83fdf650b002331f7

Author: Jason Edmeades <us at edmeades.me.uk>
Date:   Wed Apr 11 22:25:52 2007 +0100

cmd.exe: Add move support for wildcards and directories.

---

 programs/cmd/builtins.c |   87 ++++++++++++++++++++++++++++++++++------------
 1 files changed, 64 insertions(+), 23 deletions(-)

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 @@ void WCMD_if (char *p) {
  * 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);
+  /* 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);
+
+  /* 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);
     }
-    FindClose (hff);
-  }
 
-  status = MoveFile (param1, outpath);
-  if (!status) WCMD_print_error ();
+    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 @@ void WCMD_remove_dir (char *command) {
  * WCMD_rename
  *
  * Rename a file.
- * FIXME: Needs input and output files to be fully specified.
  */
 
 void WCMD_rename (void) {




More information about the wine-cvs mailing list