mirror of
https://github.com/reactos/reactos.git
synced 2025-07-28 12:01:55 +00:00
Samuel Erdtman <samuel@erdtman.se>
- Implement 'replace' command in cmd. - TODO: Update all translations with the new text strings for replace command. svn path=/trunk/; revision=29240
This commit is contained in:
parent
cc8fa40f41
commit
815cfb4aa2
8 changed files with 654 additions and 3 deletions
|
@ -347,6 +347,8 @@ INT GetRedirection (LPTSTR, LPTSTR, LPTSTR, LPTSTR, LPINT);
|
|||
/* Prototypes for REN.C */
|
||||
INT cmd_rename (LPTSTR, LPTSTR);
|
||||
|
||||
/* Prototypes for REN.C */
|
||||
INT cmd_replace (LPTSTR, LPTSTR);
|
||||
|
||||
/* Prototypes for SCREEN.C */
|
||||
INT CommandScreen (LPTSTR, LPTSTR);
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
<file>prompt.c</file>
|
||||
<file>redir.c</file>
|
||||
<file>ren.c</file>
|
||||
<file>replace.c</file>
|
||||
<file>screen.c</file>
|
||||
<file>set.c</file>
|
||||
<file>shift.c</file>
|
||||
|
@ -82,4 +83,4 @@
|
|||
<file>cmd.rc</file>
|
||||
<file>main.c</file>
|
||||
</module>
|
||||
</group>
|
||||
</group>
|
||||
|
|
|
@ -176,6 +176,10 @@ COMMAND cmds[] =
|
|||
{_T("rename"), 0, cmd_rename},
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_CMD_REPLACE
|
||||
{_T("replace"), 0, cmd_replace},
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_CMD_RMDIR
|
||||
{_T("rmdir"), CMD_SPECIAL, cmd_rmdir},
|
||||
#endif
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#define INCLUDE_CMD_PROMPT
|
||||
#define INCLUDE_CMD_RMDIR
|
||||
#define INCLUDE_CMD_RENAME
|
||||
#define INCLUDE_CMD_REPLACE
|
||||
#define INCLUDE_CMD_SCREEN
|
||||
#define INCLUDE_CMD_SET
|
||||
#define INCLUDE_CMD_START
|
||||
|
|
|
@ -47,6 +47,7 @@ pause.c Implements pause command
|
|||
prompt.c Prompt handling functions
|
||||
redir.c Redirection and piping parsing functions
|
||||
ren.c Implements rename command
|
||||
replace.c Implements replace command
|
||||
set.c Implements set command
|
||||
shift.c Implements shift command
|
||||
time.c Implements time command
|
||||
|
|
|
@ -390,6 +390,46 @@ STRING_REN_HELP2, " %lu file renamed\n"
|
|||
|
||||
STRING_REN_HELP3, " %lu files renamed\n"
|
||||
|
||||
STRING_REPLACE_HELP1, "Replaces files.\n\n\
|
||||
REPLACE [drive1:][path1]filename [drive2:][path2] [/A] [/P] [/R] [/W]\n\
|
||||
REPLACE [drive1:][path1]filename [drive2:][path2] [/P] [/R] [/S] [/W] [/U]\n\n\
|
||||
[drive1:][path1]filename Specifies the source file or files.\n\
|
||||
[drive2:][path2] Specifies the directory where files are to be\n\
|
||||
replaced.\n\
|
||||
/A Adds new files to destination directory. Cannot\n\
|
||||
use with /S or /U switches.\n\
|
||||
/P Prompts for confirmation before replacing a file or\n\
|
||||
adding a source file.\n\
|
||||
/R Replaces read-only files as well as unprotected\n\
|
||||
files.\n\
|
||||
/S Replaces files in all subdirectories of the\n\
|
||||
destination directory. Cannot use with the /A\n\
|
||||
switch.\n\
|
||||
/W Waits for you to insert a disk before beginning.\n\
|
||||
/U Replaces (updates) only files that are older than\n\
|
||||
source files. Cannot use with the /A switch.\n"
|
||||
|
||||
STRING_REPLACE_HELP2, "Source path required\n"
|
||||
|
||||
STRING_REPLACE_HELP3, "No files replaced\n"
|
||||
|
||||
STRING_REPLACE_HELP4, "%lu file(s) replaced\n"
|
||||
|
||||
STRING_REPLACE_HELP5, "Replacing %s\n"
|
||||
|
||||
STRING_REPLACE_HELP6, "Replace %s\n"
|
||||
|
||||
STRING_REPLACE_HELP7, "No files added\n"
|
||||
|
||||
STRING_REPLACE_HELP8, "%lu file(s) added\n"
|
||||
|
||||
STRING_REPLACE_HELP9, "Add %s (Y/N) "
|
||||
|
||||
STRING_REPLACE_HELP10, "Replace %s (Y/N) "
|
||||
|
||||
STRING_REPLACE_HELP11, "Adding %s\n"
|
||||
|
||||
|
||||
STRING_SHIFT_HELP, "Changes the position of replaceable parameters in a batch file.\n\n\
|
||||
SHIFT [DOWN]"
|
||||
|
||||
|
@ -548,6 +588,7 @@ RD Removes a directory.\n\
|
|||
REM Records comments (remarks) in batch files.\n\
|
||||
REN Renames a file or files.\n\
|
||||
RENAME Renames a file or files.\n\
|
||||
REPLACE Replaces files.\n\
|
||||
RMDIR Removes a directory.\n\
|
||||
SCREEN Move cursor and optionally print text.\n\
|
||||
SET Displays, sets, or removes ReactOS environment variables.\n\
|
||||
|
@ -636,6 +677,14 @@ STRING_ERROR_DRIVER_NOT_READY, "Drive not ready"
|
|||
|
||||
STRING_PATH_ERROR, "CMD: Not in environment '%s'\n"
|
||||
|
||||
STRING_REPLACE_ERROR1, "Invalid switch - %s\n"
|
||||
STRING_REPLACE_ERROR2, "Path not found - %s\n"
|
||||
STRING_REPLACE_ERROR3, "The filename, directory name, or volume label syntax is incorrect.\n"
|
||||
STRING_REPLACE_ERROR4, "Invalid parameter combination\n"
|
||||
STRING_REPLACE_ERROR5, "Access denied - %s\n"
|
||||
STRING_REPLACE_ERROR6, "No files found - %s\n"
|
||||
STRING_REPLACE_ERROR7, "Extended Error 32\n"
|
||||
|
||||
STRING_CMD_SHELLINFO, "\nReactOS Command Line Interpreter"
|
||||
STRING_VERSION_RUNVER, " running on %s"
|
||||
STRING_COPY_FILE , " %d file(s) copied\n"
|
||||
|
|
576
reactos/base/shell/cmd/replace.c
Normal file
576
reactos/base/shell/cmd/replace.c
Normal file
|
@ -0,0 +1,576 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Command shell
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: base/shell/cmd/replace.c
|
||||
* PURPOSE: Implements 'replace' cmd command
|
||||
* PROGRAMMERS: Samuel Erdtman (samuel@erdtman.se)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <precomp.h>
|
||||
|
||||
#ifdef INCLUDE_CMD_REPLACE
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
enum
|
||||
{
|
||||
REPLACE_ADD = 0x001, /* /A */
|
||||
REPLACE_CONFIRM = 0x002, /* /P */
|
||||
REPLACE_READ_ONLY = 0x004, /* /R */
|
||||
REPLACE_SUBDIR = 0x008, /* /S */
|
||||
REPLACE_DISK = 0x010, /* /W */
|
||||
REPLACE_UPDATE = 0x020, /* /U */
|
||||
};
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*just makes a print out if there is a problem with the switches*/
|
||||
void invalid_switch(LPTSTR is)
|
||||
{
|
||||
TCHAR szMsg[RC_STRING_MAX_SIZE];
|
||||
|
||||
LoadString(CMD_ModuleHandle, STRING_REPLACE_ERROR1, szMsg, RC_STRING_MAX_SIZE);
|
||||
ConOutPrintf(szMsg,is);
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_HELP3);
|
||||
}
|
||||
|
||||
/*retrives the pathe dependen om the input file name*/
|
||||
void getPath(TCHAR* out, LPTSTR in)
|
||||
{
|
||||
if(_tcslen(in) == 2 && in[1] == _T(':'))
|
||||
GetRootPath(in,out,MAX_PATH);
|
||||
else
|
||||
GetFullPathName (in, MAX_PATH, out, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*makes the replace*/
|
||||
INT replace(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], DWORD dwFlags, BOOL *doMore)
|
||||
{
|
||||
TCHAR szMsg[RC_STRING_MAX_SIZE];
|
||||
TCHAR d[MAX_PATH];
|
||||
TCHAR s[MAX_PATH];
|
||||
HANDLE hFileSrc, hFileDest;
|
||||
DWORD dwAttrib, dwRead, dwWritten;
|
||||
LPBYTE buffer;
|
||||
BOOL bEof = FALSE;
|
||||
FILETIME srcCreationTime, destCreationTime, srcLastAccessTime, destLastAccessTime;
|
||||
FILETIME srcLastWriteTime, destLastWriteTime;
|
||||
GetPathCase(source, s);
|
||||
GetPathCase(dest, d);
|
||||
s[0] = _totupper(s[0]);
|
||||
d[0] = _totupper(d[0]);
|
||||
// ConOutPrintf(_T("old-src: %s\n"), s);
|
||||
// ConOutPrintf(_T("old-dest: %s\n"), d);
|
||||
// ConOutPrintf(_T("src: %s\n"), source);
|
||||
// ConOutPrintf(_T("dest: %s\n"), dest);
|
||||
|
||||
/* Open up the sourcefile */
|
||||
hFileSrc = CreateFile (source, GENERIC_READ, FILE_SHARE_READ,NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFileSrc == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LoadString(CMD_ModuleHandle, STRING_COPY_ERROR1, szMsg, RC_STRING_MAX_SIZE);
|
||||
ConOutPrintf(szMsg, source);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the time from source file to be used in the comparison with
|
||||
dest time if update switch is set */
|
||||
GetFileTime (hFileSrc, &srcCreationTime, &srcLastAccessTime, &srcLastWriteTime);
|
||||
|
||||
/* Retrieve the source attributes so that they later on can be
|
||||
inserted in to the destination */
|
||||
dwAttrib = GetFileAttributes (source);
|
||||
|
||||
if(IsExistingFile (dest))
|
||||
{
|
||||
/* Resets the attributes to avoid probles with read only files,
|
||||
checks for read only has been made earlier */
|
||||
SetFileAttributes(dest,FILE_ATTRIBUTE_NORMAL);
|
||||
/* Is the update flas set? The time has to be controled so that
|
||||
only older files are replaced */
|
||||
if(dwFlags & REPLACE_UPDATE)
|
||||
{
|
||||
/* Read destination time */
|
||||
hFileDest = CreateFile(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
0, NULL);
|
||||
|
||||
if (hFileSrc == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LoadString(CMD_ModuleHandle, STRING_COPY_ERROR1, szMsg, RC_STRING_MAX_SIZE);
|
||||
ConOutPrintf(szMsg, dest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compare time */
|
||||
GetFileTime (hFileDest, &destCreationTime, &destLastAccessTime, &destLastWriteTime);
|
||||
if(!((srcLastWriteTime.dwHighDateTime > destLastWriteTime.dwHighDateTime) ||
|
||||
( srcLastWriteTime.dwHighDateTime == destLastWriteTime.dwHighDateTime &&
|
||||
srcLastWriteTime.dwLowDateTime > destLastWriteTime.dwLowDateTime)))
|
||||
{
|
||||
CloseHandle (hFileSrc);
|
||||
CloseHandle (hFileDest);
|
||||
return 0;
|
||||
}
|
||||
CloseHandle (hFileDest);
|
||||
}
|
||||
/* Delete the old file */
|
||||
DeleteFile (dest);
|
||||
}
|
||||
|
||||
/* Check confirm flag, and take appropriate action */
|
||||
if(dwFlags & REPLACE_CONFIRM)
|
||||
{
|
||||
/* Output depending on add flag */
|
||||
if(dwFlags & REPLACE_ADD)
|
||||
LoadString(CMD_ModuleHandle, STRING_REPLACE_HELP9, szMsg, RC_STRING_MAX_SIZE);
|
||||
else
|
||||
LoadString(CMD_ModuleHandle, STRING_REPLACE_HELP10, szMsg, RC_STRING_MAX_SIZE);
|
||||
ConOutPrintf(szMsg, dest);
|
||||
if( !FilePromptYNA (_T("")))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Output depending on add flag */
|
||||
if(dwFlags & REPLACE_ADD)
|
||||
LoadString(CMD_ModuleHandle, STRING_REPLACE_HELP11, szMsg, RC_STRING_MAX_SIZE);
|
||||
else
|
||||
LoadString(CMD_ModuleHandle, STRING_REPLACE_HELP5, szMsg, RC_STRING_MAX_SIZE);
|
||||
ConOutPrintf(szMsg,dest);
|
||||
|
||||
/* Make sure source and destination is not the same */
|
||||
if(!_tcscmp(s, d))
|
||||
{
|
||||
ConOutResPaging(TRUE, STRING_REPLACE_ERROR7);
|
||||
CloseHandle (hFileSrc);
|
||||
*doMore = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Open destination file to write to */
|
||||
hFileDest = CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
||||
if (hFileDest == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle (hFileSrc);
|
||||
ConOutResPaging(TRUE, STRING_REPLACE_ERROR7);
|
||||
*doMore = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get buffer for the copy process */
|
||||
buffer = (LPBYTE)VirtualAlloc(NULL, BUFF_SIZE, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
CloseHandle (hFileDest);
|
||||
CloseHandle (hFileSrc);
|
||||
ConOutResPaging(TRUE, STRING_ERROR_OUT_OF_MEMORY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Put attribute and time to the new destination file */
|
||||
SetFileAttributes (dest, dwAttrib);
|
||||
SetFileTime (hFileDest, &srcCreationTime, &srcLastAccessTime, &srcLastWriteTime);
|
||||
do
|
||||
{
|
||||
/* Read data from source */
|
||||
ReadFile (hFileSrc, buffer, BUFF_SIZE, &dwRead, NULL);
|
||||
|
||||
/* Done? */
|
||||
if (dwRead == 0)
|
||||
break;
|
||||
|
||||
/* Write to destination file */
|
||||
WriteFile (hFileDest, buffer, dwRead, &dwWritten, NULL);
|
||||
|
||||
/* Done! or ctrl break! */
|
||||
if (dwWritten != dwRead || CheckCtrlBreak(BREAK_INPUT))
|
||||
{
|
||||
ConOutResPuts(STRING_COPY_ERROR3);
|
||||
cmd_free (buffer);
|
||||
CloseHandle (hFileDest);
|
||||
CloseHandle (hFileSrc);
|
||||
nErrorLevel = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
while (!bEof);
|
||||
|
||||
/* Return memory and close files */
|
||||
VirtualFree (buffer, 0, MEM_RELEASE);
|
||||
CloseHandle (hFileDest);
|
||||
CloseHandle (hFileSrc);
|
||||
|
||||
/* Return one file replaced */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Function to iterate over source files and call replace for each of them */
|
||||
INT recReplace(DWORD dwFlags, TCHAR szSrcPath[MAX_PATH], TCHAR szDestPath[MAX_PATH], BOOL *doMore)
|
||||
{
|
||||
TCHAR szMsg[RC_STRING_MAX_SIZE], tmpDestPath[MAX_PATH], tmpSrcPath[MAX_PATH];
|
||||
INT filesReplaced=0, i;
|
||||
DWORD dwAttrib = 0;
|
||||
HANDLE hFile;
|
||||
WIN32_FIND_DATA findBuffer;
|
||||
|
||||
/* Get file handel to the sourcefile(s) */
|
||||
hFile = FindFirstFile (szSrcPath, &findBuffer);
|
||||
|
||||
/* Strip the paths back to the folder they are in, so that the diffrent
|
||||
filenames can be added if more than one */
|
||||
for(i = (_tcslen(szSrcPath) - 1); i > -1; i--)
|
||||
if(szSrcPath[i] != _T('\\'))
|
||||
szSrcPath[i] = _T('\0');
|
||||
else
|
||||
break;
|
||||
|
||||
/* Go through all the soursfiles and copy/replace them */
|
||||
do
|
||||
{
|
||||
if(CheckCtrlBreak(BREAK_INPUT))
|
||||
{
|
||||
return filesReplaced;
|
||||
}
|
||||
|
||||
/* Problem with file handler */
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
return filesReplaced;
|
||||
|
||||
/* We do not want to replace any .. . ocr directory */
|
||||
if(!_tcscmp (findBuffer.cFileName, _T(".")) ||
|
||||
!_tcscmp (findBuffer.cFileName, _T(".."))||
|
||||
findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
continue;
|
||||
|
||||
/* Add filename to destpath */
|
||||
_tcscpy(tmpDestPath,szDestPath);
|
||||
_tcscat (tmpDestPath, findBuffer.cFileName);
|
||||
|
||||
dwAttrib = GetFileAttributes(tmpDestPath);
|
||||
/* Check add flag */
|
||||
if(dwFlags & REPLACE_ADD)
|
||||
{
|
||||
if(IsExistingFile(tmpDestPath))
|
||||
continue;
|
||||
else
|
||||
dwAttrib = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!IsExistingFile(tmpDestPath))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if file is read only, if so check if that should be ignored */
|
||||
if(dwAttrib & FILE_ATTRIBUTE_READONLY)
|
||||
{
|
||||
if(!(dwFlags & REPLACE_READ_ONLY))
|
||||
{
|
||||
LoadString(CMD_ModuleHandle, STRING_REPLACE_ERROR5, szMsg, RC_STRING_MAX_SIZE);
|
||||
ConOutPrintf(szMsg, tmpDestPath);
|
||||
*doMore = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add filename to sourcepath, insted of wildcards */
|
||||
_tcscpy(tmpSrcPath,szSrcPath);
|
||||
_tcscat (tmpSrcPath, findBuffer.cFileName);
|
||||
|
||||
/* Make the replace */
|
||||
if(replace(tmpSrcPath,tmpDestPath, dwFlags, doMore))
|
||||
{
|
||||
filesReplaced++;
|
||||
}
|
||||
else if (!*doMore)
|
||||
{
|
||||
/* The file to be replaced was the same as the source */
|
||||
filesReplaced = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Take next sourcefile if any */
|
||||
}while(FindNextFile (hFile, &findBuffer));
|
||||
|
||||
return filesReplaced;
|
||||
}
|
||||
|
||||
/* If /s switch is specifyed all subdirs has to be considered */
|
||||
INT recFindSubDirs(DWORD dwFlags,
|
||||
TCHAR szSrcPath[MAX_PATH],
|
||||
TCHAR szDestPath[MAX_PATH],
|
||||
BOOL *doMore)
|
||||
{
|
||||
HANDLE hFile;
|
||||
WIN32_FIND_DATA findBuffer;
|
||||
TCHAR tmpDestPath[MAX_PATH], tmpSrcPath[MAX_PATH];
|
||||
INT filesReplaced = 0, i;
|
||||
|
||||
/* Add a wildcard to dest end so the it will be easy to itterate
|
||||
over all the files and directorys in the dest directory */
|
||||
_tcscat(szDestPath, _T("*"));
|
||||
|
||||
/* Get the first file in the directory */
|
||||
hFile = FindFirstFile (szDestPath, &findBuffer);
|
||||
|
||||
/* Remove the star added earlyer to dest path */
|
||||
for(i = (_tcslen(szDestPath) - 1); i > -1; i--)
|
||||
if(szDestPath[i] != _T('\\'))
|
||||
szDestPath[i] = _T('\0');
|
||||
else
|
||||
break;
|
||||
|
||||
/* Iterate over all filed directories in the dest dir */
|
||||
do
|
||||
{
|
||||
/* Save the source path so that it will not be wrecked */
|
||||
_tcscpy(tmpSrcPath,szSrcPath);
|
||||
/* Check for reading problems */
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ConOutFormatMessage (GetLastError(), tmpSrcPath);
|
||||
return filesReplaced;
|
||||
}
|
||||
|
||||
/* Check if the we should enter the dir or if it is a file
|
||||
or . or .. if so thake the next object to process */
|
||||
if(!_tcscmp (findBuffer.cFileName, _T(".")) ||
|
||||
!_tcscmp (findBuffer.cFileName, _T(".."))||
|
||||
IsExistingFile(findBuffer.cFileName))
|
||||
continue;
|
||||
/* Add the destpath and the new dir path to tempDestPath */
|
||||
_tcscpy(tmpDestPath,szDestPath);
|
||||
_tcscat (tmpDestPath, findBuffer.cFileName);
|
||||
/* Make sure that we have a directory */
|
||||
if(IsExistingDirectory(tmpDestPath))
|
||||
{
|
||||
/* Add a \ to the end or the path */
|
||||
if(szDestPath[_tcslen(tmpDestPath) - 1] != _T('\\'))
|
||||
_tcscat(tmpDestPath, _T("\\"));
|
||||
/* Call the function to replace files in the new directory */
|
||||
filesReplaced += recReplace(dwFlags, tmpSrcPath, tmpDestPath, doMore);
|
||||
/* If there were problems break e.g. read-only file */
|
||||
if(!*doMore)
|
||||
break;
|
||||
_tcscpy(tmpSrcPath,szSrcPath);
|
||||
/* Controle the next level of subdirs */
|
||||
filesReplaced += recFindSubDirs(dwFlags,tmpSrcPath,tmpDestPath, doMore);
|
||||
if(!*doMore)
|
||||
break;
|
||||
}
|
||||
/* Get the next handle */
|
||||
} while(FindNextFile (hFile, &findBuffer));
|
||||
|
||||
return filesReplaced;
|
||||
}
|
||||
|
||||
INT cmd_replace (LPTSTR cmd, LPTSTR param)
|
||||
{
|
||||
TCHAR szMsg[RC_STRING_MAX_SIZE];
|
||||
LPTSTR *arg;
|
||||
INT argc, i,filesReplaced = 0, nFiles, srcIndex = -1, destIndex = -1;
|
||||
DWORD dwFlags = 0;
|
||||
TCHAR szDestPath[MAX_PATH], szSrcPath[MAX_PATH], tmpSrcPath[MAX_PATH];
|
||||
BOOL doMore = TRUE;
|
||||
|
||||
/* Help wanted? */
|
||||
if (!_tcsncmp (param, _T("/?"), 2))
|
||||
{
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_HELP1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Divide the argument in to an array of c-strings */
|
||||
arg = split (param, &argc, FALSE);
|
||||
nFiles = argc;
|
||||
|
||||
/* Read options */
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (arg[i][0] == _T('/'))
|
||||
{
|
||||
if (_tcslen(arg[i]) == 2)
|
||||
{
|
||||
switch (_totupper(arg[i][1]))
|
||||
{
|
||||
case _T('A'):
|
||||
dwFlags |= REPLACE_ADD;
|
||||
break;
|
||||
case _T('P'):
|
||||
dwFlags |= REPLACE_CONFIRM;
|
||||
break;
|
||||
case _T('R'):
|
||||
dwFlags |= REPLACE_READ_ONLY;
|
||||
break;
|
||||
case _T('S'):
|
||||
dwFlags |= REPLACE_SUBDIR;
|
||||
break;
|
||||
case _T('W'):
|
||||
dwFlags |= REPLACE_DISK;
|
||||
break;
|
||||
case _T('U'):
|
||||
dwFlags |= REPLACE_UPDATE;
|
||||
break;
|
||||
default:
|
||||
invalid_switch(arg[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
invalid_switch(arg[i]);
|
||||
freep(arg);
|
||||
return 0;
|
||||
}
|
||||
nFiles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(srcIndex == -1)
|
||||
{
|
||||
srcIndex = i;
|
||||
}
|
||||
else if(destIndex == -1)
|
||||
{
|
||||
destIndex = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
invalid_switch(arg[i]);
|
||||
freep(arg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* See so that at least source is there */
|
||||
if (nFiles < 1)
|
||||
{
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_HELP2);
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_HELP3);
|
||||
freep(arg);
|
||||
return 1;
|
||||
}
|
||||
/* Check so that not both update and add switch is added and subdir */
|
||||
if((dwFlags & REPLACE_UPDATE || dwFlags & REPLACE_SUBDIR) && (dwFlags & REPLACE_ADD))
|
||||
{
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_ERROR4);
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_HELP7);
|
||||
freep(arg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If we have a destination get the full path */
|
||||
if(destIndex != -1)
|
||||
{
|
||||
if(_tcslen(arg[destIndex]) == 2 && arg[destIndex][1] == ':')
|
||||
GetRootPath(arg[destIndex],szDestPath,MAX_PATH);
|
||||
else
|
||||
{
|
||||
/* Check for wildcards in destination directory */
|
||||
if (_tcschr (arg[destIndex], _T('*')) != NULL ||
|
||||
_tcschr (arg[destIndex], _T('?')) != NULL)
|
||||
{
|
||||
LoadString(CMD_ModuleHandle, STRING_REPLACE_ERROR2, szMsg, RC_STRING_MAX_SIZE);
|
||||
ConOutPrintf(szMsg,arg[destIndex]);
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_HELP3);
|
||||
freep(arg);
|
||||
return 1;
|
||||
}
|
||||
getPath(szDestPath, arg[destIndex]);
|
||||
/* Make sure that destination exists */
|
||||
if(!IsExistingDirectory(szDestPath))
|
||||
{
|
||||
LoadString(CMD_ModuleHandle, STRING_REPLACE_ERROR2, szMsg, RC_STRING_MAX_SIZE);
|
||||
ConOutPrintf(szMsg, szDestPath);
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_HELP3);
|
||||
freep(arg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Dest is current dir */
|
||||
GetCurrentDirectory(MAX_PATH,szDestPath);
|
||||
}
|
||||
|
||||
/* Get the full source path */
|
||||
if(!(_tcslen(arg[srcIndex]) == 2 && arg[srcIndex][1] == ':'))
|
||||
getPath(szSrcPath, arg[srcIndex]);
|
||||
else
|
||||
_tcscpy(szSrcPath,arg[srcIndex]);
|
||||
|
||||
/* Source does not have wildcards */
|
||||
if (_tcschr (arg[srcIndex], _T('*')) == NULL &&
|
||||
_tcschr (arg[srcIndex], _T('?')) == NULL)
|
||||
{
|
||||
/* Check so that source is not a directory, because that is not allowed */
|
||||
if(IsExistingDirectory(szSrcPath))
|
||||
{
|
||||
LoadString(CMD_ModuleHandle, STRING_REPLACE_ERROR6, szMsg, RC_STRING_MAX_SIZE);
|
||||
ConOutPrintf(szMsg, szSrcPath);
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_HELP3);
|
||||
freep(arg);
|
||||
return 1;
|
||||
}
|
||||
/* Check if the file exists */
|
||||
if(!IsExistingFile(szSrcPath))
|
||||
{
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_HELP3);
|
||||
freep(arg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* /w switch is set so wait for any key to be pressed */
|
||||
if(dwFlags & REPLACE_DISK)
|
||||
{
|
||||
msg_pause();
|
||||
cgetchar();
|
||||
}
|
||||
|
||||
/* Add an extra \ to the destination path if needed */
|
||||
if(szDestPath[_tcslen(szDestPath) - 1] != _T('\\'))
|
||||
_tcscat(szDestPath, _T("\\"));
|
||||
|
||||
/* Save source path */
|
||||
_tcscpy(tmpSrcPath,szSrcPath);
|
||||
/* Replace in dest dir */
|
||||
filesReplaced += recReplace(dwFlags, tmpSrcPath, szDestPath, &doMore);
|
||||
/* If subdir switch is set replace in the subdirs to */
|
||||
if(dwFlags & REPLACE_SUBDIR && doMore)
|
||||
{
|
||||
filesReplaced += recFindSubDirs(dwFlags, szSrcPath, szDestPath, &doMore);
|
||||
}
|
||||
|
||||
/* If source == dest write no more */
|
||||
if(filesReplaced != -1)
|
||||
{
|
||||
/* No files replaced */
|
||||
if(filesReplaced==0)
|
||||
{
|
||||
/* Add switch dependent output */
|
||||
if(dwFlags & REPLACE_ADD)
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_HELP7);
|
||||
else
|
||||
ConOutResPaging(TRUE,STRING_REPLACE_HELP3);
|
||||
}
|
||||
/* Some files replaced */
|
||||
else
|
||||
{
|
||||
/* Add switch dependent output */
|
||||
if(dwFlags & REPLACE_ADD)
|
||||
LoadString(CMD_ModuleHandle, STRING_REPLACE_HELP8, szMsg, RC_STRING_MAX_SIZE);
|
||||
else
|
||||
LoadString(CMD_ModuleHandle, STRING_REPLACE_HELP4, szMsg, RC_STRING_MAX_SIZE);
|
||||
ConOutPrintf(szMsg, filesReplaced);
|
||||
}
|
||||
}
|
||||
/* Return memory */
|
||||
freep(arg);
|
||||
return 1;
|
||||
}
|
||||
#endif /* INCLUDE_CMD_REPLACE */
|
|
@ -63,8 +63,13 @@
|
|||
#define STRING_TIME_ERROR1 348
|
||||
#define STRING_TYPE_ERROR1 349
|
||||
#define STRING_WINDOW_ERROR1 350
|
||||
|
||||
|
||||
#define STRING_REPLACE_ERROR1 351
|
||||
#define STRING_REPLACE_ERROR2 352
|
||||
#define STRING_REPLACE_ERROR3 353
|
||||
#define STRING_REPLACE_ERROR4 354
|
||||
#define STRING_REPLACE_ERROR5 355
|
||||
#define STRING_REPLACE_ERROR6 356
|
||||
#define STRING_REPLACE_ERROR7 357
|
||||
|
||||
#define STRING_ATTRIB_HELP 600
|
||||
#define STRING_ALIAS_HELP 601
|
||||
|
@ -223,6 +228,18 @@
|
|||
#define STRING_MD_ERROR 725
|
||||
#define STRING_MD_ERROR2 726
|
||||
|
||||
#define STRING_REPLACE_HELP1 727
|
||||
#define STRING_REPLACE_HELP2 728
|
||||
#define STRING_REPLACE_HELP3 729
|
||||
#define STRING_REPLACE_HELP4 730
|
||||
#define STRING_REPLACE_HELP5 731
|
||||
#define STRING_REPLACE_HELP6 732
|
||||
#define STRING_REPLACE_HELP7 733
|
||||
#define STRING_REPLACE_HELP8 734
|
||||
#define STRING_REPLACE_HELP9 735
|
||||
#define STRING_REPLACE_HELP10 736
|
||||
#define STRING_REPLACE_HELP11 737
|
||||
|
||||
|
||||
/* These strings are language independent (cmd.rc) */
|
||||
#define STRING_FREEDOS_DEV 800
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue