mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
Implemented useful rename command.
svn path=/trunk/; revision=2302
This commit is contained in:
parent
32ec8c6868
commit
20bec3cf6b
4 changed files with 241 additions and 30 deletions
|
@ -26,7 +26,7 @@ BEGIN
|
||||||
VALUE "FileVersion", CMD_VER_RC
|
VALUE "FileVersion", CMD_VER_RC
|
||||||
VALUE "InternalName", "cmd\0"
|
VALUE "InternalName", "cmd\0"
|
||||||
VALUE "OriginalCopyright", "Copyright (C) 1994-1998 Tim Norman and others\0"
|
VALUE "OriginalCopyright", "Copyright (C) 1994-1998 Tim Norman and others\0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 1998-2000 Eric Kohl\0"
|
VALUE "LegalCopyright", "Copyright (C) 1998-2001 Eric Kohl and others\0"
|
||||||
VALUE "OriginalFilename", "cmd.exe\0"
|
VALUE "OriginalFilename", "cmd.exe\0"
|
||||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#define CMD_VER "0.1.1"
|
#define CMD_VER "0.1.2"
|
||||||
#define CMD_VER_RC CMD_VER"\0"
|
#define CMD_VER_RC CMD_VER"\0"
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
*
|
*
|
||||||
* 20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>
|
* 20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>
|
||||||
* Unicode and redirection safe!
|
* Unicode and redirection safe!
|
||||||
|
*
|
||||||
|
* 17-Oct-2001 (Eric Kohl <ekohl@rz.online.de>
|
||||||
|
* Implemented basic rename code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -21,50 +24,258 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
|
#include "batch.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
REN_ATTRIBUTES = 0x001, /* /A : not implemented */
|
||||||
|
REN_ERROR = 0x002, /* /E */
|
||||||
|
REN_NOTHING = 0x004, /* /N */
|
||||||
|
REN_PROMPT = 0x008, /* /P : not implemented */
|
||||||
|
REN_QUIET = 0x010, /* /Q */
|
||||||
|
REN_SUBDIR = 0x020, /* /S */
|
||||||
|
REN_TOTAL = 0x040, /* /T */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* simple file rename internal command.
|
* file rename internal command.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
INT cmd_rename (LPTSTR cmd, LPTSTR param)
|
INT cmd_rename (LPTSTR cmd, LPTSTR param)
|
||||||
{
|
{
|
||||||
LPTSTR *arg;
|
LPTSTR *arg = NULL;
|
||||||
INT argc;
|
INT args = 0;
|
||||||
|
INT nEvalArgs = 0; /* nunber of evaluated arguments */
|
||||||
|
DWORD dwFlags = 0;
|
||||||
|
DWORD dwFiles = 0; /* number of renamedd files */
|
||||||
|
INT i;
|
||||||
|
LPTSTR srcPattern = NULL;
|
||||||
|
LPTSTR dstPattern = NULL;
|
||||||
|
TCHAR dstFile[MAX_PATH];
|
||||||
|
BOOL bDstWildcard = FALSE;
|
||||||
|
|
||||||
if (!_tcsncmp (param, _T("/?"), 2))
|
LPTSTR p,q,r;
|
||||||
|
|
||||||
|
HANDLE hFile;
|
||||||
|
WIN32_FIND_DATA f;
|
||||||
|
|
||||||
|
if (!_tcsncmp(param, _T("/?"), 2))
|
||||||
{
|
{
|
||||||
ConOutPuts (_T("Renames a file/directory or files/directories.\n"
|
ConOutPuts(_T("Renames a file/directory or files/directories.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"RENAME [drive:][path][directoryname1 | filename1] [directoryname2 | filename2]\n"
|
"RENAME [/E /N /P /Q /S /T] old_name ... new_name\n"
|
||||||
"REN [drive:][path][directoryname1 | filename1] [directoryname2 | filename2]\n"
|
"REN [/E /N /P /Q /S /T] old_name ... new_name\n"
|
||||||
|
"\n"
|
||||||
|
" /E No eror messages.\n"
|
||||||
|
" /N Nothing.\n"
|
||||||
|
" /P Prompts for confirmation before renaming each file.\n"
|
||||||
|
" (Not implemented yet!)\n"
|
||||||
|
" /Q Quiet.\n"
|
||||||
|
" /S Rename subdirectories.\n"
|
||||||
|
" /T Display total number of renamed files.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Note that you cannot specify a new drive or path for your destination. Use\n"
|
"Note that you cannot specify a new drive or path for your destination. Use\n"
|
||||||
"the MOVE command for that purpose."));
|
"the MOVE command for that purpose."));
|
||||||
return 0;
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* split the argument list */
|
/* split the argument list */
|
||||||
arg = split (param, &argc);
|
arg = split(param, &args);
|
||||||
|
|
||||||
if (argc != 2)
|
if (args < 2)
|
||||||
{
|
{
|
||||||
freep (arg);
|
if (!(dwFlags & REN_ERROR))
|
||||||
error_too_many_parameters (param);
|
error_req_param_missing();
|
||||||
return 1;
|
freep(arg);
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MoveFile (arg[0], arg[1]))
|
/* read options */
|
||||||
|
for (i = 0; i < args; i++)
|
||||||
{
|
{
|
||||||
ConErrPuts (_T("rename"));
|
if (*arg[i] == _T('/'))
|
||||||
freep (arg);
|
{
|
||||||
return 1;
|
if (_tcslen(arg[i]) >= 2)
|
||||||
|
{
|
||||||
|
switch (_totupper(arg[i][1]))
|
||||||
|
{
|
||||||
|
case _T('E'):
|
||||||
|
dwFlags |= REN_ERROR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _T('N'):
|
||||||
|
dwFlags |= REN_NOTHING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _T('P'):
|
||||||
|
dwFlags |= REN_PROMPT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _T('Q'):
|
||||||
|
dwFlags |= REN_QUIET;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _T('S'):
|
||||||
|
dwFlags |= REN_SUBDIR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _T('T'):
|
||||||
|
dwFlags |= REN_TOTAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nEvalArgs++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
freep (arg);
|
/* keep quiet within batch files */
|
||||||
|
if (bc != NULL)
|
||||||
|
dwFlags |= REN_QUIET;
|
||||||
|
|
||||||
return 0;
|
/* there are only options on the command line --> error!!! */
|
||||||
|
if (args < nEvalArgs + 2)
|
||||||
|
{
|
||||||
|
if (!(dwFlags & REN_ERROR))
|
||||||
|
error_req_param_missing();
|
||||||
|
freep(arg);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get destination pattern */
|
||||||
|
for (i = 0; i < args; i++)
|
||||||
|
{
|
||||||
|
if (*arg[i] == _T('/'))
|
||||||
|
continue;
|
||||||
|
dstPattern = arg[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_tcschr(dstPattern, _T('*')) || _tcschr(dstPattern, _T('?')))
|
||||||
|
bDstWildcard = TRUE;
|
||||||
|
|
||||||
|
/* enumerate source patterns */
|
||||||
|
for (i = 0; i < args; i++)
|
||||||
|
{
|
||||||
|
if (*arg[i] == _T('/') || arg[i] == dstPattern)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
srcPattern = arg[i];
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
ConErrPrintf(_T("\n\nSourcePattern: %s\n"), srcPattern);
|
||||||
|
ConErrPrintf(_T("DestinationPattern: %s\n"), dstPattern);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hFile = FindFirstFile(srcPattern, &f);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
if (!(dwFlags & REN_ERROR))
|
||||||
|
error_file_not_found();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* ignore "." and ".." */
|
||||||
|
if (!_tcscmp (f.cFileName, _T(".")) ||
|
||||||
|
!_tcscmp (f.cFileName, _T("..")))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* do not rename hidden or system files */
|
||||||
|
if (f.dwAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* do not rename directories when the destination pattern contains
|
||||||
|
* wildcards, unless option /S is used */
|
||||||
|
if ((f.dwAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
&& bDstWildcard
|
||||||
|
&& !(dwFlags & REN_SUBDIR))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
ConErrPrintf(_T("Found source name: %s\n"), f.cFileName);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* build destination file name */
|
||||||
|
p = f.cFileName;
|
||||||
|
q = dstPattern;
|
||||||
|
r = dstFile;
|
||||||
|
while(*q != 0)
|
||||||
|
{
|
||||||
|
if (*q == '*')
|
||||||
|
{
|
||||||
|
q++;
|
||||||
|
while (*p != 0 && *p != *q)
|
||||||
|
{
|
||||||
|
*r = *p;
|
||||||
|
p++;
|
||||||
|
r++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*q == '?')
|
||||||
|
{
|
||||||
|
q++;
|
||||||
|
if (*p != 0)
|
||||||
|
{
|
||||||
|
*r = *p;
|
||||||
|
p++;
|
||||||
|
r++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*r = *q;
|
||||||
|
if (*p != 0)
|
||||||
|
p++;
|
||||||
|
q++;
|
||||||
|
r++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*r = 0;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
ConErrPrintf(_T("DestinationFile: %s\n"), dstFile);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(dwFlags & REN_QUIET) && !(dwFlags & REN_TOTAL))
|
||||||
|
ConOutPrintf(_T("%s -> %s\n"), f.cFileName, dstFile);
|
||||||
|
|
||||||
|
/* rename the file */
|
||||||
|
if (!(dwFlags & REN_NOTHING))
|
||||||
|
{
|
||||||
|
if (MoveFile(f.cFileName, dstFile))
|
||||||
|
{
|
||||||
|
dwFiles++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(dwFlags & REN_ERROR))
|
||||||
|
ConErrPrintf(_T("MoveFile() failed. Error: %lu\n"), GetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (FindNextFile(hFile, &f));
|
||||||
|
FindClose(hFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dwFlags & REN_QUIET))
|
||||||
|
{
|
||||||
|
if (dwFiles == 1)
|
||||||
|
ConOutPrintf(_T(" %lu file renamed\n"),
|
||||||
|
dwFiles);
|
||||||
|
else
|
||||||
|
ConOutPrintf(_T(" %lu files renamed\n"),
|
||||||
|
dwFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
freep(arg);
|
||||||
|
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
|
@ -128,7 +128,7 @@ INT cmd_ver (LPTSTR cmd, LPTSTR param)
|
||||||
"\n"
|
"\n"
|
||||||
"ReactOS version written by:\n"
|
"ReactOS version written by:\n"
|
||||||
" Eric Kohl Emanuele Aliberti\n"
|
" Eric Kohl Emanuele Aliberti\n"
|
||||||
" Paolo Pantaleo\n"));
|
" Paolo Pantaleo Phillip Susi\n"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue