Implemented useful rename command.

svn path=/trunk/; revision=2302
This commit is contained in:
Eric Kohl 2001-10-17 18:30:10 +00:00
parent 32ec8c6868
commit 20bec3cf6b
4 changed files with 241 additions and 30 deletions

View file

@ -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

View file

@ -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"

View file

@ -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"
"\n"
"RENAME [/E /N /P /Q /S /T] old_name ... new_name\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"
"Note that you cannot specify a new drive or path for your destination. Use\n"
"the MOVE command for that purpose."));
return(0);
}
/* split the argument list */
arg = split(param, &args);
if (args < 2)
{
if (!(dwFlags & REN_ERROR))
error_req_param_missing();
freep(arg);
return(1);
}
/* read options */
for (i = 0; i < args; i++)
{
if (*arg[i] == _T('/'))
{ {
ConOutPuts (_T("Renames a file/directory or files/directories.\n" if (_tcslen(arg[i]) >= 2)
"\n" {
"RENAME [drive:][path][directoryname1 | filename1] [directoryname2 | filename2]\n" switch (_totupper(arg[i][1]))
"REN [drive:][path][directoryname1 | filename1] [directoryname2 | filename2]\n" {
"\n" case _T('E'):
"Note that you cannot specify a new drive or path for your destination. Use\n" dwFlags |= REN_ERROR;
"the MOVE command for that purpose.")); break;
return 0;
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++;
}
}
/* keep quiet within batch files */
if (bc != NULL)
dwFlags |= REN_QUIET;
/* 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;
} }
/* split the argument list */ do
arg = split (param, &argc);
if (argc != 2)
{ {
freep (arg); /* ignore "." and ".." */
error_too_many_parameters (param); if (!_tcscmp (f.cFileName, _T(".")) ||
return 1; !_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 (!MoveFile (arg[0], arg[1])) if (!(dwFlags & REN_QUIET))
{ {
ConErrPuts (_T("rename")); if (dwFiles == 1)
freep (arg); ConOutPrintf(_T(" %lu file renamed\n"),
return 1; dwFiles);
} else
ConOutPrintf(_T(" %lu files renamed\n"),
dwFiles);
}
freep (arg); freep(arg);
return 0; return(0);
} }
#endif #endif
/* EOF */

View file

@ -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
{ {