ReactOS 0.4.16-dev-311-g9382aa2
ren.c
Go to the documentation of this file.
1/*
2 * REN.C - rename internal command.
3 *
4 *
5 * History:
6 *
7 *
8 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
9 * added config.h include
10 *
11 * 18-Dec-1998 (Eric Kohl)
12 * Added support for quoted long file names with spaces.
13 *
14 * 20-Jan-1999 (Eric Kohl)
15 * Unicode and redirection safe!
16 *
17 * 17-Oct-2001 (Eric Kohl)
18 * Implemented basic rename code.
19 *
20 * 30-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
21 * Remove all hardcoded strings in En.rc
22 *
23 * 25-Nov-2008 (Victor Martinez <vicmarcal@hotmail.com>)
24 * Patch dedicated to Myrjala because her comprehension and love :D
25 * Fixing following Bugs:
26 * -Wrong behavior with wildcards when Source and Destiny are Paths(FIXED).
27 * -Wrong general behavior (MSDN:"Rename cant move files between subdirectories")(FIXED)
28 * -Wrong behavior when renaming without path in destiny:(i.e) "ren C:\text\as.txt list.txt" it moves as.txt and then rename it(FIXED)
29 * (MSDN: If there is a Path in Source and no Path in Destiny, then Destiny Path is Source Path,because never Ren has to be used to move.)
30 * -Implemented checkings if SourcePath and DestinyPath are differents.
31 *
32 */
33
34#include "precomp.h"
35
36#ifdef INCLUDE_CMD_RENAME
37
38enum
39{
40 REN_ATTRIBUTES = 0x001, /* /A : not implemented */
41 REN_ERROR = 0x002, /* /E */
42 REN_NOTHING = 0x004, /* /N */
43 REN_PROMPT = 0x008, /* /P : not implemented */
44 REN_QUIET = 0x010, /* /Q */
45 REN_SUBDIR = 0x020, /* /S */
46 REN_TOTAL = 0x040, /* /T */
47};
48
49
50/*
51 * file rename internal command.
52 */
54{
55 LPTSTR *arg = NULL;
56 INT args = 0;
57 INT nSlash = 0;
58 INT nEvalArgs = 0; /* number of evaluated arguments */
59 DWORD dwFlags = 0;
60 DWORD dwFiles = 0; /* number of renamed files */
61 INT i;
62
63 LPTSTR srcPattern = NULL; /* Source Argument*/
64 TCHAR srcPath[MAX_PATH]; /*Source Path Directories*/
65 LPTSTR srcFILE = NULL; /*Contains the files name(s)*/
66 TCHAR srcFinal[MAX_PATH];
67
68 LPTSTR dstPattern = NULL; /*Destiny Argument*/
69 TCHAR dstPath[MAX_PATH]; /*Source Path Directories*/
70 LPTSTR dstFILE = NULL; /*Contains the files name(s)*/
71
72 TCHAR dstLast[MAX_PATH]; /*It saves the File name after unmasked with wildcards*/
73 TCHAR dstFinal[MAX_PATH]; /*It saves the Final destiny Path*/
74
75 BOOL bDstWildcard = FALSE;
76 BOOL bPath = FALSE;
77
78 LPTSTR p,q,r;
79
82 /*If the PARAM=/? then show the help*/
83 if (!_tcsncmp(param, _T("/?"), 2))
84 {
86 return 0;
87 }
88
89 nErrorLevel = 0;
90
91 /* Split the argument list.Args will be saved in arg vector*/
93
94 if (args < 2)
95 {
96 if (!(dwFlags & REN_ERROR))
98 freep(arg);
99 return 1;
100 }
101
102 /* Read options */
103 for (i = 0; i < args; i++)
104 {
105 /* Lets check if we have a special option chosen and set the flag(s)*/
106 if (*arg[i] == _T('/'))
107 {
108 if (_tcslen(arg[i]) >= 2)
109 {
110 switch (_totupper(arg[i][1]))
111 {
112 case _T('E'):
114 break;
115
116 case _T('N'):
118 break;
119
120 case _T('P'):
122 break;
123
124 case _T('Q'):
126 break;
127
128 case _T('S'):
130 break;
131
132 case _T('T'):
134 break;
135 }
136 }
137 nEvalArgs++;//Save the number of the options.
138 }
139 }
140
141 /* keep quiet within batch files */
142 if (bc != NULL)
144
145 /* there are only options on the command line --> error!!! */
146 if (args < nEvalArgs + 2)
147 {
148 if (!(dwFlags & REN_ERROR))
150 freep(arg);
151 return 1;
152 }
153
154 /* Get destination pattern and source pattern*/
155 for (i = 0; i < args; i++)
156 {
157 if (*arg[i] == _T('/'))//We have find an Option.Jump it.
158 continue;
159 dstPattern = arg[i]; //we save the Last argument as dstPattern
160 srcPattern = arg[i-1];
161 }
162
163 if (_tcschr(srcPattern, _T('\\'))) //Checking if the Source (srcPattern) is a Path to the file
164 {
165 bPath= TRUE;
166
167 //Splitting srcPath and srcFile.
168
169 srcFILE = _tcschr(srcPattern, _T('\\'));
170 nSlash++;
171 while(_tcschr(srcFILE, _T('\\')))
172 {
173 srcFILE++;
174 if (*srcFILE==_T('\\')) nSlash++ ;
175 if (!_tcschr(srcFILE, _T('\\'))) break;
176 }
177 _tcsncpy(srcPath,srcPattern,_tcslen(srcPattern)-_tcslen(srcFILE));
178
179 if (_tcschr(dstPattern, _T('\\'))) //Checking if the Destiny (dstPattern)is also a Path.And splitting dstPattern in dstPath and srcPath.
180 {
181 dstFILE = _tcschr(dstPattern, _T('\\'));
182 nSlash=0;
183 while(_tcschr(dstFILE, _T('\\')))
184 {
185 dstFILE++;
186 if (*dstFILE==_T('\\')) nSlash++ ;
187 if (!_tcschr(dstFILE, _T('\\'))) break;
188 }
189 _tcsncpy(dstPath,dstPattern,_tcslen(dstPattern)-_tcslen(dstFILE));
190
191 if ((_tcslen(dstPath)!=_tcslen(srcPath))||(_tcsncmp(srcPath,dstPath,_tcslen(srcPath))!=0)) //If it has a Path,then MUST be equal than srcPath
192 {
193 error_syntax(dstPath);
194 freep(arg);
195 return 1;
196 }
197 }
198 else
199 { //If Destiny hasnt a Path,then (MSDN says) srcPath is its Path.
200 _tcscpy(dstPath,srcPath);
201 dstFILE=dstPattern;
202 }
203 }
204
205 if (!_tcschr(srcPattern, _T('\\'))) //If srcPattern isn't a Path but a name:
206 {
207 srcFILE=srcPattern;
208 if (_tcschr(dstPattern, _T('\\')))
209 {
210 error_syntax(dstPattern);
211 freep(arg);
212 return 1;
213 }
214 else
215 {
216 dstFILE=dstPattern;
217 }
218 }
219
220 //Checking Wildcards.
221 if (_tcschr(dstFILE, _T('*')) || _tcschr(dstFILE, _T('?')))
222 bDstWildcard = TRUE;
223
224 TRACE("\n\nSourcePattern: %s SourcePath: %s SourceFile: %s", debugstr_aw(srcPattern),debugstr_aw(srcPath),debugstr_aw(srcFILE));
225 TRACE("\n\nDestinationPattern: %s Destination Path:%s Destination File: %s\n", debugstr_aw(dstPattern),debugstr_aw(dstPath),debugstr_aw(dstFILE));
226
227 hFile = FindFirstFile(srcPattern, &f);
228
230 {
232 }
233 do
234 {
235 /* ignore "." and ".." */
236 if (!_tcscmp (f.cFileName, _T(".")) || !_tcscmp (f.cFileName, _T("..")))
237 continue;
238
239 /* do not rename hidden or system files */
240 if (f.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
241 continue;
242
243 /* do not rename directories when the destination pattern contains
244 * wildcards, unless option /S is used */
245 if ((f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
246 bDstWildcard && !(dwFlags & REN_SUBDIR))
247 {
248 continue;
249 }
250
251 TRACE("Found source name: %s\n", debugstr_aw(f.cFileName));
252 /* So here we have splitted the dstFILE and we have find a f.cFileName(thanks to srcPattern)
253 * Now we have to use the mask (dstFILE) (which can have Wildcards) with f.cFileName to find destination file name(dstLast) */
254 p = f.cFileName;
255 q = dstFILE;
256 r = dstLast;
257 while(*q != 0)
258 {
259 if (*q == '*')
260 {
261 q++;
262 while (*p != 0 && *p != *q)
263 {
264 *r = *p;
265 p++;
266 r++;
267 }
268 }
269 else if (*q == '?')
270 {
271 q++;
272 if (*p != 0)
273 {
274 *r = *p;
275 p++;
276 r++;
277 }
278 }
279 else
280 {
281 *r = *q;
282 if (*p != 0) p++;
283 q++;
284 r++;
285 }
286 }
287 *r = 0;
288 //Well we have splitted the Paths,so now we have to paste them again(if needed),thanks bPath.
289 if (bPath != FALSE)
290 {
291 _tcscpy(srcFinal,srcPath);
292 _tcscat(srcFinal,f.cFileName);
293 _tcscpy(dstFinal,dstPath);
294 _tcscat(dstFinal,dstLast);
295 }
296 else
297 {
298 _tcscpy(srcFinal,f.cFileName);
299 _tcscpy(dstFinal,dstLast);
300 }
301
302 TRACE("DestinationPath: %s\n", debugstr_aw(dstFinal));
303
304 if (!(dwFlags & REN_QUIET) && !(dwFlags & REN_TOTAL))
305 ConOutPrintf(_T("%s -> %s\n"),srcFinal , dstFinal);
306
307 /* Rename the file */
308 if (!(dwFlags & REN_NOTHING))
309 {
310 if (MoveFile(srcFinal, dstFinal))
311 {
312 dwFiles++;
313 }
314 else
315 {
316 if (!(dwFlags & REN_ERROR))
318 }
319 }
320 }
321 while (FindNextFile(hFile, &f));
322
323 //Closing and Printing errors.
325
326 if (!(dwFlags & REN_QUIET))
327 {
328 if (dwFiles == 1)
330 else
332 }
333
334 freep(arg);
335 return 0;
336}
337
338#endif
339
340/* EOF */
PBATCH_CONTEXT bc
Definition: batch.c:67
INT nErrorLevel
Definition: cmd.c:158
VOID error_file_not_found(VOID)
Definition: error.c:93
VOID error_req_param_missing(VOID)
Definition: error.c:110
VOID error_syntax(PCTSTR s)
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:178
#define ConOutPrintf(szStr,...)
Definition: console.h:41
#define ConErrResPrintf(uID,...)
Definition: console.h:50
#define debugstr_aw
Definition: precomp.h:44
#define STRING_REN_HELP3
Definition: resource.h:165
#define STRING_REN_ERROR
Definition: resource.h:63
#define STRING_REN_HELP2
Definition: resource.h:164
#define STRING_REN_HELP1
Definition: resource.h:163
static VOID freep(LPSTR *p)
Definition: cmdcons.c:98
static LPSTR * split(LPSTR s, LPINT args)
Definition: cmdcons.c:163
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLuint srcPath
Definition: glext.h:11718
GLfloat f
Definition: glext.h:7540
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define _tcscmp
Definition: tchar.h:1424
#define _tcscat
Definition: tchar.h:622
#define _tcscpy
Definition: tchar.h:623
#define _tcsncpy
Definition: tchar.h:1410
#define _tcsncmp
Definition: tchar.h:1428
#define _totupper
Definition: tchar.h:1509
#define _tcschr
Definition: tchar.h:1406
#define f
Definition: ke_i.h:83
_In_ HANDLE hFile
Definition: mswsock.h:90
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
@ REN_NOTHING
Definition: ren.c:42
@ REN_PROMPT
Definition: ren.c:43
@ REN_SUBDIR
Definition: ren.c:45
@ REN_ATTRIBUTES
Definition: ren.c:40
@ REN_QUIET
Definition: ren.c:44
@ REN_TOTAL
Definition: ren.c:46
@ REN_ERROR
Definition: ren.c:41
INT cmd_rename(LPTSTR param)
Definition: ren.c:53
#define ConOutResPrintf(uID,...)
Definition: replace.h:31
#define args
Definition: format.c:66
#define TRACE(s)
Definition: solgame.cpp:4
Definition: match.c:390
int32_t INT
Definition: typedefs.h:58
#define _T(x)
Definition: vfdio.h:22
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define MoveFile
Definition: winbase.h:3902
#define FindNextFile
Definition: winbase.h:3813
#define FindFirstFile
Definition: winbase.h:3807
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
char TCHAR
Definition: xmlstorage.h:189
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define _tcslen
Definition: xmlstorage.h:198