update for HEAD-2003050101
[reactos.git] / subsys / system / cmd / move.c
1 /*
2  *  MOVE.C - move internal command.
3  *
4  *
5  *  History:
6  *
7  *    14-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
8  *        Started.
9  *
10  *    18-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
11  *        Unicode safe!
12  *        Preliminary version!!!
13  *
14  *    20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
15  *        Redirection safe!
16  *
17  *    27-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
18  *        Added help text ("/?").
19  *        Added more error checks.
20  *
21  *    03-Feb-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
22  *        Added "/N" option.
23  */
24
25 #include "config.h"
26
27 #ifdef INCLUDE_CMD_MOVE
28
29 #include <windows.h>
30 #include <tchar.h>
31 #include <string.h>
32 #include <ctype.h>
33
34 #include "cmd.h"
35
36
37 #define OVERWRITE_NO     0
38 #define OVERWRITE_YES    1
39 #define OVERWRITE_ALL    2
40 #define OVERWRITE_CANCEL 3
41
42
43 static INT Overwrite (LPTSTR fn)
44 {
45         TCHAR inp[10];
46         LPTSTR p;
47
48         ConOutPrintf (_T("Overwrite %s (Yes/No/All)? "), fn);
49         ConInString (inp, 10);
50
51         _tcsupr (inp);
52         for (p=inp; _istspace (*p); p++)
53                 ;
54
55         if (*p != _T('Y') && *p != _T('A'))
56                 return OVERWRITE_NO;
57         if (*p == _T('A'))
58                 return OVERWRITE_ALL;
59
60         return OVERWRITE_YES;
61 }
62
63
64
65 INT cmd_move (LPTSTR cmd, LPTSTR param)
66 {
67         LPTSTR *arg;
68         INT argc, i, nFiles;
69         TCHAR szDestPath[MAX_PATH];
70         TCHAR szSrcPath[MAX_PATH];
71         BOOL bPrompt = TRUE;
72         LPTSTR p;
73         WIN32_FIND_DATA findBuffer;
74         HANDLE hFile;
75         LPTSTR pszFile;
76         BOOL   bNothing = FALSE;
77
78         if (!_tcsncmp (param, _T("/?"), 2))
79         {
80 #if 0
81                 ConOutPuts (_T("Moves files and renames files and directories.\n\n"
82                                "To move one or more files:\n"
83                                "MOVE [/N][/Y|/-Y][drive:][path]filename1[,...] destination\n"
84                                "\n"
85                                "To rename a directory:\n"
86                                "MOVE [/N][/Y|/-Y][drive:][path]dirname1 dirname2\n"
87                                "\n"
88                                "  [drive:][path]filename1  Specifies the location and name of the file\n"
89                                "                           or files you want to move.\n"
90                                "  /N                       Nothing. Don everthing but move files or direcories.\n"
91                                "  /Y\n"
92                                "  /-Y\n"
93                                "..."));
94 #else
95                 ConOutPuts (_T("Moves files and renames files and directories.\n\n"
96                                "To move one or more files:\n"
97                                "MOVE [/N][drive:][path]filename1[,...] destination\n"
98                                "\n"
99                                "To rename a directory:\n"
100                                "MOVE [/N][drive:][path]dirname1 dirname2\n"
101                                "\n"
102                                "  [drive:][path]filename1  Specifies the location and name of the file\n"
103                                "                           or files you want to move.\n"
104                                "  /N                       Nothing. Don everthing but move files or direcories.\n"
105                                "\n"
106                                "Current limitations:\n"
107                                "  - You can't move a file or directory from one drive to another.\n"
108                                ));
109 #endif
110                 return 0;
111         }
112
113         arg = split (param, &argc, FALSE);
114         nFiles = argc;
115
116         /* read options */
117         for (i = 0; i < argc; i++)
118         {
119                 p = arg[i];
120
121                 if (*p == _T('/'))
122                 {
123                         p++;
124                         if (*p == _T('-'))
125                         {
126                                 p++;
127                                 if (_totupper (*p) == _T('Y'))
128                                         bPrompt = TRUE;
129                         }
130                         else
131                         {
132                                 if (_totupper (*p) == _T('Y'))
133                                         bPrompt = FALSE;
134                                 else if  (_totupper (*p) == _T('N'))
135                                         bNothing = TRUE;
136                         }
137                         nFiles--;
138                 }
139         }
140
141         if (nFiles < 2)
142         {
143                 /* there must be at least two pathspecs */
144                 error_req_param_missing ();
145                 return 1;
146         }
147
148         /* get destination */
149         GetFullPathName (arg[argc - 1], MAX_PATH, szDestPath, NULL);
150 #ifdef _DEBUG
151         DebugPrintf (_T("Destination: %s\n"), szDestPath);
152 #endif
153
154         /* move it*/
155         for (i = 0; i < argc - 1; i++)
156         {
157                 if (*arg[i] == _T('/'))
158                         continue;
159
160                 hFile = FindFirstFile (arg[i], &findBuffer);
161                 if (hFile == INVALID_HANDLE_VALUE)
162                 {
163                         ErrorMessage (GetLastError (), arg[i]);
164                         freep (arg);
165                         return 1;
166                 }
167
168                 do
169                 {
170                         GetFullPathName (findBuffer.cFileName, MAX_PATH, szSrcPath, &pszFile);
171
172                         if (GetFileAttributes (szSrcPath) & FILE_ATTRIBUTE_DIRECTORY)
173                         {
174                                 /* source is directory */
175
176 #ifdef _DEBUG
177                                 DebugPrintf (_T("Move directory \'%s\' to \'%s\'\n"),
178                                                          szSrcPath, szDestPath);
179 #endif
180                                 if (!bNothing)
181                                 {
182                                         MoveFile (szSrcPath, szDestPath);
183                                 }
184                         }
185                         else
186                         {
187                                 /* source is file */
188
189                                 if (IsValidFileName (szDestPath))
190                                 {
191                                         /* destination exists */
192                                         if (GetFileAttributes (szDestPath) & FILE_ATTRIBUTE_DIRECTORY)
193                                         {
194                                                 /* destination is existing directory */
195
196                                                 TCHAR szFullDestPath[MAX_PATH];
197
198                                                 _tcscpy (szFullDestPath, szDestPath);
199                                                 _tcscat (szFullDestPath, _T("\\"));
200                                                 _tcscat (szFullDestPath, pszFile);
201
202                                                 ConOutPrintf (_T("%s => %s"), szSrcPath, szFullDestPath);
203
204                                                 if (!bNothing)
205                                                 {
206                                                         if (MoveFile (szSrcPath, szFullDestPath))
207                                                                 ConOutPrintf (_T("[OK]\n"));
208                                                         else
209                                                                 ConOutPrintf (_T("[Error]\n"));
210                                                 }
211                                         }
212                                         else
213                                         {
214                                                 /* destination is existing file */
215                                                 INT nOverwrite;
216
217                                                 /* must get the overwrite code */
218                                                 if ((nOverwrite = Overwrite (szDestPath)))
219                                                 {
220 #if 0
221                                                         if (nOverwrite == OVERWRITE_ALL)
222                                                                 *lpFlags |= FLAG_OVERWRITE_ALL;
223 #endif
224                                                         ConOutPrintf (_T("%s => %s"), szSrcPath, szDestPath);
225
226                                                         if (!bNothing)
227                                                         {
228                                                                 if (MoveFile (szSrcPath, szDestPath))
229                                                                         ConOutPrintf (_T("[OK]\n"));
230                                                                 else
231                                                                         ConOutPrintf (_T("[Error]\n"));
232                                                         }
233                                                 }
234                                         }
235                                 }
236                                 else
237                                 {
238                                         /* destination does not exist */
239                                         TCHAR szFullDestPath[MAX_PATH];
240
241                                         GetFullPathName (szDestPath, MAX_PATH, szFullDestPath, NULL);
242
243                                         ConOutPrintf (_T("%s => %s"), szSrcPath, szFullDestPath);
244
245                                         if (!bNothing)
246                                         {
247                                                 if (MoveFile (szSrcPath, szFullDestPath))
248                                                         ConOutPrintf (_T("[OK]\n"));
249                                                 else
250                                                         ConOutPrintf (_T("[Error]\n"));
251                                         }
252                                 }
253                         }
254                 }
255                 while (FindNextFile (hFile, &findBuffer));
256
257                 FindClose (hFile);
258         }
259
260         freep (arg);
261
262         return 0;
263 }
264
265 #endif /* INCLUDE_CMD_MOVE */