- Remove hard-coded reference to cmdstart.bat and load it from registry (Software...
[reactos.git] / reactos / base / shell / cmd / ren.c
1 /*
2 * REN.C - rename internal command.
3 *
4 *
5 * History:
6 *
7 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
8 * added config.h include
9 *
10 * 18-Dec-1998 (Eric Kohl)
11 * Added support for quoted long file names with spaces.
12 *
13 * 20-Jan-1999 (Eric Kohl)
14 * Unicode and redirection safe!
15 *
16 * 17-Oct-2001 (Eric Kohl)
17 * Implemented basic rename code.
18 *
19 * 30-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
20 * Remove all hardcode string to En.rc
21 */
22
23 #include <precomp.h>
24
25 #ifdef INCLUDE_CMD_RENAME
26
27 enum
28 {
29 REN_ATTRIBUTES = 0x001, /* /A : not implemented */
30 REN_ERROR = 0x002, /* /E */
31 REN_NOTHING = 0x004, /* /N */
32 REN_PROMPT = 0x008, /* /P : not implemented */
33 REN_QUIET = 0x010, /* /Q */
34 REN_SUBDIR = 0x020, /* /S */
35 REN_TOTAL = 0x040, /* /T */
36 };
37
38
39 /*
40 * file rename internal command.
41 *
42 */
43 INT cmd_rename (LPTSTR cmd, LPTSTR param)
44 {
45 TCHAR szMsg[RC_STRING_MAX_SIZE];
46 LPTSTR *arg = NULL;
47 INT args = 0;
48 INT nEvalArgs = 0; /* nunber of evaluated arguments */
49 DWORD dwFlags = 0;
50 DWORD dwFiles = 0; /* number of renamedd files */
51 INT i;
52 LPTSTR srcPattern = NULL;
53 LPTSTR dstPattern = NULL;
54 TCHAR dstFile[MAX_PATH];
55 BOOL bDstWildcard = FALSE;
56
57 LPTSTR p,q,r;
58
59 HANDLE hFile;
60 WIN32_FIND_DATA f;
61
62 if (!_tcsncmp(param, _T("/?"), 2))
63 {
64 ConOutResPaging(TRUE,STRING_REN_HELP1);
65 return 0;
66 }
67
68 nErrorLevel = 0;
69
70 /* split the argument list */
71 arg = split(param, &args, FALSE);
72
73 if (args < 2)
74 {
75 if (!(dwFlags & REN_ERROR))
76 error_req_param_missing();
77 freep(arg);
78 return 1;
79 }
80
81 /* read options */
82 for (i = 0; i < args; i++)
83 {
84 if (*arg[i] == _T('/'))
85 {
86 if (_tcslen(arg[i]) >= 2)
87 {
88 switch (_totupper(arg[i][1]))
89 {
90 case _T('E'):
91 dwFlags |= REN_ERROR;
92 break;
93
94 case _T('N'):
95 dwFlags |= REN_NOTHING;
96 break;
97
98 case _T('P'):
99 dwFlags |= REN_PROMPT;
100 break;
101
102 case _T('Q'):
103 dwFlags |= REN_QUIET;
104 break;
105
106 case _T('S'):
107 dwFlags |= REN_SUBDIR;
108 break;
109
110 case _T('T'):
111 dwFlags |= REN_TOTAL;
112 break;
113 }
114 }
115 nEvalArgs++;
116 }
117 }
118
119 /* keep quiet within batch files */
120 if (bc != NULL)
121 dwFlags |= REN_QUIET;
122
123 /* there are only options on the command line --> error!!! */
124 if (args < nEvalArgs + 2)
125 {
126 if (!(dwFlags & REN_ERROR))
127 error_req_param_missing();
128 freep(arg);
129 return 1;
130 }
131
132 /* get destination pattern */
133 for (i = 0; i < args; i++)
134 {
135 if (*arg[i] == _T('/'))
136 continue;
137 dstPattern = arg[i];
138 }
139
140 if (_tcschr(dstPattern, _T('*')) || _tcschr(dstPattern, _T('?')))
141 bDstWildcard = TRUE;
142
143 /* enumerate source patterns */
144 for (i = 0; i < args; i++)
145 {
146 if (*arg[i] == _T('/') || arg[i] == dstPattern)
147 continue;
148
149 srcPattern = arg[i];
150
151 #ifdef _DEBUG
152 ConErrPrintf(_T("\n\nSourcePattern: %s\n"), srcPattern);
153 ConErrPrintf(_T("DestinationPattern: %s\n"), dstPattern);
154 #endif
155
156 hFile = FindFirstFile(srcPattern, &f);
157 if (hFile == INVALID_HANDLE_VALUE)
158 {
159 if (!(dwFlags & REN_ERROR))
160 error_file_not_found();
161 continue;
162 }
163
164 do
165 {
166 /* ignore "." and ".." */
167 if (!_tcscmp (f.cFileName, _T(".")) ||
168 !_tcscmp (f.cFileName, _T("..")))
169 continue;
170
171 /* do not rename hidden or system files */
172 if (f.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
173 continue;
174
175 /* do not rename directories when the destination pattern contains
176 * wildcards, unless option /S is used */
177 if ((f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
178 && bDstWildcard
179 && !(dwFlags & REN_SUBDIR))
180 continue;
181
182 #ifdef _DEBUG
183 ConErrPrintf(_T("Found source name: %s\n"), f.cFileName);
184 #endif
185
186 /* build destination file name */
187 p = f.cFileName;
188 q = dstPattern;
189 r = dstFile;
190 while(*q != 0)
191 {
192 if (*q == '*')
193 {
194 q++;
195 while (*p != 0 && *p != *q)
196 {
197 *r = *p;
198 p++;
199 r++;
200 }
201 }
202 else if (*q == '?')
203 {
204 q++;
205 if (*p != 0)
206 {
207 *r = *p;
208 p++;
209 r++;
210 }
211 }
212 else
213 {
214 *r = *q;
215 if (*p != 0)
216 p++;
217 q++;
218 r++;
219 }
220 }
221 *r = 0;
222
223 #ifdef _DEBUG
224 ConErrPrintf(_T("DestinationFile: %s\n"), dstFile);
225 #endif
226
227 if (!(dwFlags & REN_QUIET) && !(dwFlags & REN_TOTAL))
228 ConOutPrintf(_T("%s -> %s\n"), f.cFileName, dstFile);
229
230 /* rename the file */
231 if (!(dwFlags & REN_NOTHING))
232 {
233 if (MoveFile(f.cFileName, dstFile))
234 {
235 dwFiles++;
236 }
237 else
238 {
239 if (!(dwFlags & REN_ERROR))
240 {
241 LoadString(CMD_ModuleHandle, STRING_REN_ERROR1, szMsg, RC_STRING_MAX_SIZE);
242 ConErrPrintf(szMsg, GetLastError());
243 }
244 }
245 }
246 }
247 while (FindNextFile(hFile, &f));
248 FindClose(hFile);
249 }
250
251 if (!(dwFlags & REN_QUIET))
252 {
253 if (dwFiles == 1)
254 LoadString( CMD_ModuleHandle, STRING_REN_HELP2, szMsg, RC_STRING_MAX_SIZE);
255 else
256 LoadString( CMD_ModuleHandle, STRING_REN_HELP3, szMsg, RC_STRING_MAX_SIZE);
257 ConOutPrintf(szMsg,dwFiles);
258 }
259
260 freep(arg);
261
262 return 0;
263 }
264
265 #endif
266
267 /* EOF */