irc nick jjkola, Jyrki Jaakkola <jjkola@email.com> frist patch solv to move file from a vol to another, and move mulite file same time. (not tested in ros) it works in windows with ros cmd. The patch are not very clean , but it fix alot of bugs also in move.

svn path=/trunk/; revision=16695
This commit is contained in:
Magnus Olsen 2005-07-22 23:15:54 +00:00
parent 7aad44a4f5
commit 6af5a6f78f

View file

@ -34,7 +34,6 @@
#ifdef INCLUDE_CMD_MOVE
enum
{
MOVE_NOTHING = 0x001, /* /N */
@ -42,6 +41,18 @@ enum
MOVE_OVER_NO = 0x004, /* /-Y */
};
enum
{ /* Move status flags */
MOVE_SOURCE_IS_DIR = 0x001,
MOVE_SOURCE_IS_FILE = 0x002,
MOVE_DEST_IS_DIR = 0x004,
MOVE_DEST_IS_FILE = 0x008,
MOVE_SOURCE_HAS_WILD = 0x010, /* source has wildcard */
MOVE_SRC_CURRENT_IS_DIR = 0x020, /* source is file but at the current round we found a directory */
MOVE_DEST_EXISTS = 0x040,
MOVE_PATHS_ON_DIF_VOL = 0x080 /* source and destination paths are on different volume */
};
static INT Overwrite (LPTSTR fn)
{
/*ask the user if they want to override*/
@ -53,6 +64,26 @@ static INT Overwrite (LPTSTR fn)
return res;
}
void GetDirectory (LPTSTR wholepath, LPTSTR directory)
{
/* returns only directory part of path with backslash */
/* TODO: make code unc aware */
/* Is there a better alternative to this? */
LPTSTR last;
if (IsExistingDirectory(wholepath))
{
_tcscpy(directory, wholepath);
}
else if ((last = _tcsrchr(wholepath,_T('\\'))) != NULL)
{
_tcsncpy(directory, wholepath, last - wholepath + 1);
directory[last - wholepath + 1] = 0;
}
else
{
GetRootPath(wholepath,directory, MAX_PATH);
}
}
INT cmd_move (LPTSTR cmd, LPTSTR param)
@ -61,12 +92,30 @@ INT cmd_move (LPTSTR cmd, LPTSTR param)
LPTSTR *arg;
INT argc, i, nFiles;
TCHAR szDestPath[MAX_PATH];
TCHAR szFullDestPath[MAX_PATH];
TCHAR szSrcDirPath[MAX_PATH];
TCHAR szSrcPath[MAX_PATH];
TCHAR szFullSrcPath[MAX_PATH];
DWORD dwFlags = 0;
INT nOverwrite = 0;
WIN32_FIND_DATA findBuffer;
HANDLE hFile;
/* used only when source and destination directories are on different volume*/
HANDLE hDestFile;
WIN32_FIND_DATA findDestBuffer;
TCHAR szMoveDest[MAX_PATH];
TCHAR szMoveSrc[MAX_PATH];
LPTSTR pszDestDirPointer;
LPTSTR pszSrcDirPointer;
INT nDirLevel = 0;
LPTSTR pszFile;
BOOL OnlyOneFile;
BOOL FoundFile;
BOOL MoveStatus;
DWORD dwMoveFlags = 0;
DWORD dwMoveStatusFlags = 0;
if (!_tcsncmp (param, _T("/?"), 2))
@ -106,11 +155,11 @@ INT cmd_move (LPTSTR cmd, LPTSTR param)
case _T('N'):
dwFlags |= MOVE_NOTHING;
break;
case _T('Y'):
dwFlags |= MOVE_OVER_YES;
break;
case _T('-'):
dwFlags |= MOVE_OVER_NO;
break;
@ -119,147 +168,385 @@ INT cmd_move (LPTSTR cmd, LPTSTR param)
nFiles--;
}
}
if (nFiles < 2)
{
/* there must be at least two pathspecs */
error_req_param_missing ();
return 1;
}
if (_tcschr (arg[argc - 1], _T('*')) != NULL)
/* check for wildcards in source and destination */
if (_tcschr (arg[argc - 1], _T('*')) != NULL || _tcschr (arg[argc - 1], _T('?')) != NULL)
{
/*'*' in dest, this doesnt happen. give folder name instead*/
error_parameter_format('2');
/* '*'/'?' in dest, this doesnt happen. give folder name instead*/
error_invalid_parameter_format(arg[argc - 1]);
return 1;
}
if (_tcschr (arg[argc - 2], _T('*')) != NULL || _tcschr (arg[argc - 2], _T('?')) != NULL)
{
dwMoveStatusFlags |= MOVE_SOURCE_HAS_WILD;
}
/* get destination */
GetFullPathName (arg[argc - 1], MAX_PATH, szDestPath, NULL);
#ifdef _DEBUG
DebugPrintf (_T("Destination: %s\n"), szDestPath);
#endif
/* move it */
for (i = 0; i < argc - 1; i++)
/* get source folder */
GetDirectory(arg[argc - 2], szSrcDirPath);
GetFullPathName(szSrcDirPath, MAX_PATH, szSrcPath, &pszFile);
_tcscpy(szSrcDirPath,szSrcPath);
/* we need following check to see if source happens to be directly given directory
and if it is then rip off last directory part so that there won't be any clashes with codes after this point */
GetFullPathName(arg[argc - 2], MAX_PATH, szSrcPath, &pszFile);
if (_tcscmp(szSrcDirPath,szSrcPath) == 0)
szSrcDirPath[pszFile - szSrcPath] = _T('\0');
#ifdef _DEBUG
DebugPrintf (_T("Source Folder: %s\n"), szSrcDirPath);
#endif
hFile = FindFirstFile (arg[argc - 2], &findBuffer);
if (hFile == INVALID_HANDLE_VALUE)
{
if (*arg[i] == _T('/'))
continue;
ErrorMessage (GetLastError (), arg[argc - 2]);
freep (arg);
return 1;
}
hFile = FindFirstFile (arg[i], &findBuffer);
if (hFile == INVALID_HANDLE_VALUE)
/* check for special cases "." and ".." and if found skip them */
FoundFile = TRUE;
while(FoundFile &&
(_tcscmp(findBuffer.cFileName,_T(".")) == 0 ||
_tcscmp(findBuffer.cFileName,_T("..")) == 0))
FoundFile = FindNextFile (hFile, &findBuffer);
if (!FoundFile)
{
/* what? we don't have anything to move? */
error_file_not_found();
FindClose(hFile);
freep(arg);
return 1;
}
OnlyOneFile = TRUE;
_tcscpy(szSrcPath,szSrcDirPath);
/*check to see if there is an ending slash, if not add one*/
if(szSrcPath[_tcslen(szSrcPath) - 1] != _T('\\'))
_tcscat (szSrcPath, _T("\\"));
_tcscat(szSrcPath,findBuffer.cFileName);
#ifdef _DEBUG
DebugPrintf (_T("Source Path: %s\n"), szSrcPath);
#endif
/* check if there can be found files as files have first priority */
if (IsExistingFile(szSrcPath)) dwMoveStatusFlags |= MOVE_SOURCE_IS_FILE;
else dwMoveStatusFlags |= MOVE_SOURCE_IS_DIR;
while(OnlyOneFile && FindNextFile(hFile,&findBuffer))
{
_tcscpy(szSrcPath,szSrcDirPath);
if(szSrcPath[_tcslen(szSrcPath) - 1] != _T('\\'))
_tcscat (szSrcPath, _T("\\"));
_tcscat(szSrcPath,findBuffer.cFileName);
if (IsExistingFile(szSrcPath))
{
ErrorMessage (GetLastError (), arg[i]);
ConOutPrintf(_T(""));
if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE) OnlyOneFile = FALSE;
else
{ /* this has been done this way so that we don't disturb other settings if they have been set before this */
dwMoveStatusFlags |= MOVE_SOURCE_IS_FILE;
dwMoveStatusFlags &= ~MOVE_SOURCE_IS_DIR;
}
}
}
FindClose(hFile);
#ifdef _DEBUG
DebugPrintf(_T("Do we have only one file: %s\n"), OnlyOneFile ? _T("TRUE") : _T("FALSE"));
#endif
/* we have to start again to be sure we don't miss any files or folders*/
hFile = FindFirstFile (arg[argc - 2], &findBuffer);
if (hFile == INVALID_HANDLE_VALUE)
{
ErrorMessage (GetLastError (), arg[argc - 2]);
freep (arg);
return 1;
}
/* check for special cases "." and ".." and if found skip them */
FoundFile = TRUE;
while(FoundFile &&
(_tcscmp(findBuffer.cFileName,_T(".")) == 0 ||
_tcscmp(findBuffer.cFileName,_T("..")) == 0))
FoundFile = FindNextFile (hFile, &findBuffer);
if (!FoundFile)
{
/* huh? somebody removed files and/or folders which were there */
error_file_not_found();
FindClose(hFile);
freep(arg);
return 1;
}
/* check if source and destination paths are on different volumes */
if (szSrcPath[0] != szDestPath[0])
dwMoveStatusFlags |= MOVE_PATHS_ON_DIF_VOL;
/* move it */
do
{
#ifdef _DEBUG
DebugPrintf (_T("Found file/directory: %s\n"), findBuffer.cFileName);
#endif
nOverwrite = 1;
dwMoveFlags = 0;
dwMoveStatusFlags &= ~MOVE_DEST_IS_FILE &
~MOVE_DEST_IS_DIR &
~MOVE_SRC_CURRENT_IS_DIR &
~MOVE_DEST_EXISTS;
_tcscpy(szFullSrcPath,szSrcDirPath);
if(szFullSrcPath[_tcslen(szFullSrcPath) - 1] != _T('\\'))
_tcscat (szFullSrcPath, _T("\\"));
_tcscat(szFullSrcPath,findBuffer.cFileName);
_tcscpy(szSrcPath, szFullSrcPath);
if (IsExistingDirectory(szSrcPath))
{
/* source is directory */
if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE)
{
dwMoveStatusFlags |= MOVE_SRC_CURRENT_IS_DIR; /* source is file but at the current round we found a directory */
continue;
}
#ifdef _DEBUG
DebugPrintf (_T("Source is dir: %s\n"), szSrcPath);
#endif
dwMoveFlags = MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED;
}
/* if source is file we don't need to do anything special */
if (IsExistingDirectory(szDestPath))
{
/* destination is existing directory */
#ifdef _DEBUG
DebugPrintf (_T("Destination is directory: %s\n"), szDestPath);
#endif
dwMoveStatusFlags |= MOVE_DEST_IS_DIR;
/*build the dest string(accounts for *)*/
_tcscpy (szFullDestPath, szDestPath);
/*check to see if there is an ending slash, if not add one*/
if(szFullDestPath[_tcslen(szFullDestPath) - 1] != _T('\\'))
_tcscat (szFullDestPath, _T("\\"));
_tcscat (szFullDestPath, findBuffer.cFileName);
if (IsExistingFile(szFullDestPath) || IsExistingDirectory(szFullDestPath))
dwMoveStatusFlags |= MOVE_DEST_EXISTS;
dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED;
}
if (IsExistingFile(szDestPath))
{
/* destination is a file */
#ifdef _DEBUG
DebugPrintf (_T("Destination is file: %s\n"), szDestPath);
#endif
dwMoveStatusFlags |= MOVE_DEST_IS_FILE | MOVE_DEST_EXISTS;
_tcscpy (szFullDestPath, szDestPath);
dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED;
}
#ifdef _DEBUG
DebugPrintf(_T("Move Status Flags: 0x%X\n"),dwMoveStatusFlags);
#endif
if (dwMoveStatusFlags & MOVE_SOURCE_IS_DIR &&
dwMoveStatusFlags & MOVE_DEST_IS_DIR &&
dwMoveStatusFlags & MOVE_SOURCE_HAS_WILD)
{
/* We are not allowed to have existing source and destination dir when there is wildcard in source */
error_syntax(NULL);
FindClose(hFile);
freep(arg);
return 1;
}
if (!(dwMoveStatusFlags & (MOVE_DEST_IS_FILE | MOVE_DEST_IS_DIR)))
{
/* destination doesn't exist */
_tcscpy (szFullDestPath, szDestPath);
if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE) dwMoveStatusFlags |= MOVE_DEST_IS_FILE;
if (dwMoveStatusFlags & MOVE_SOURCE_IS_DIR) dwMoveStatusFlags |= MOVE_DEST_IS_DIR;
dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED;
}
if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE &&
dwMoveStatusFlags & MOVE_DEST_IS_FILE &&
!OnlyOneFile)
{
/*source has many files but there is only one destination file*/
error_invalid_parameter_format(arg[argc - 1]);
FindClose(hFile);
freep (arg);
return 1;
}
do
{
nOverwrite = 1;
GetFullPathName (findBuffer.cFileName, MAX_PATH, szSrcPath, &pszFile);
if (GetFileAttributes (szSrcPath) & FILE_ATTRIBUTE_DIRECTORY)
/*checks to make sure user wanted/wants the override*/
if((dwFlags & MOVE_OVER_NO) &&
(dwMoveStatusFlags & MOVE_DEST_EXISTS))
continue;
if(!(dwFlags & MOVE_OVER_YES) &&
(dwMoveStatusFlags & MOVE_DEST_EXISTS))
nOverwrite = Overwrite (szFullDestPath);
if (nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK)
continue;
if (nOverwrite == PROMPT_ALL)
dwFlags |= MOVE_OVER_YES;
ConOutPrintf (_T("%s => %s "), szSrcPath, szFullDestPath);
/* are we really supposed to do something */
if (dwFlags & MOVE_NOTHING)
continue;
/*move the file*/
if (!(dwMoveStatusFlags & MOVE_SOURCE_IS_DIR &&
dwMoveStatusFlags & MOVE_PATHS_ON_DIF_VOL))
/* we aren't moving source folder to different drive */
MoveStatus = MoveFileEx (szSrcPath, szFullDestPath, dwMoveFlags);
else
{ /* we are moving source folder to different drive */
_tcscpy(szMoveDest, szFullDestPath);
_tcscpy(szMoveSrc, szSrcPath);
DeleteFile(szMoveDest);
MoveStatus = CreateDirectory(szMoveDest, NULL); /* we use default security settings */
if (MoveStatus)
{
/* source is directory */
#ifdef _DEBUG
DebugPrintf (_T("Move directory \'%s\' to \'%s\'\n"),
szSrcPath, szDestPath);
#endif
if (!(dwFlags & MOVE_NOTHING))
continue;
MoveFileEx (szSrcPath, szDestPath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED);
}
else
{
/* source is file */
if (GetFileAttributes (szDestPath) & FILE_ATTRIBUTE_DIRECTORY)
{
/* destination is existing directory */
/*build the dest string(accounts for *)*/
TCHAR szFullDestPath[MAX_PATH];
_tcscpy (szFullDestPath, szDestPath);
/*check to see if there is an ending slash, if not add one*/
if(szFullDestPath[_tcslen(szFullDestPath) - 1] != _T('\\'))
_tcscat (szFullDestPath, _T("\\"));
_tcscat (szFullDestPath, findBuffer.cFileName);
/*checks to make sure user wanted/wants the override*/
if((dwFlags & MOVE_OVER_NO) && IsExistingFile (szFullDestPath))
continue;
if(!(dwFlags & MOVE_OVER_YES) && IsExistingFile (szFullDestPath))
nOverwrite = Overwrite (szFullDestPath);
if (nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK)
continue;
if (nOverwrite == PROMPT_ALL)
dwFlags |= MOVE_OVER_YES;
/*delete the file that might be there first*/
DeleteFile(szFullDestPath);
ConOutPrintf (_T("%s => %s"), szSrcPath, szFullDestPath);
if ((dwFlags & MOVE_NOTHING))
continue;
/*delete the file that might be there first*/
DeleteFile(szFullDestPath);
/*move the file*/
if (MoveFileEx (szSrcPath, szFullDestPath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED))
LoadString(CMD_ModuleHandle, STRING_MOVE_ERROR1, szMsg, RC_STRING_MAX_SIZE);
else
LoadString(CMD_ModuleHandle, STRING_MOVE_ERROR2, szMsg, RC_STRING_MAX_SIZE);
ConOutPrintf(szMsg);
}
_tcscat(szMoveDest,_T("\\"));
_tcscat(szMoveSrc,_T("\\"));
nDirLevel = 0;
pszDestDirPointer = szMoveDest + _tcslen(szMoveDest);
pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc);
_tcscpy(pszSrcDirPointer,_T("*.*"));
hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer);
if (hDestFile == INVALID_HANDLE_VALUE)
MoveStatus = FALSE;
else
{
/* destination is a file */
if (_tcschr (arg[argc - 2], _T('*')) != NULL)
BOOL FirstTime = TRUE;
FoundFile = TRUE;
MoveStatus = FALSE;
while(FoundFile)
{
/*'*' in src but there should't be one in the dest*/
error_parameter_format('1');
return 1;
if (FirstTime)
FirstTime = FALSE;
else
FoundFile = FindNextFile (hDestFile, &findDestBuffer);
if (!FoundFile)
{ /* Nothing to do in this folder so we stop working on it */
FindClose(hDestFile);
(pszSrcDirPointer)--;
(pszDestDirPointer)--;
_tcscpy(pszSrcDirPointer,_T(""));
if (nDirLevel > 0)
{
TCHAR szTempPath[MAX_PATH];
INT nDiff;
FoundFile = TRUE; /* we need to continue our seek for files */
nDirLevel--;
RemoveDirectory(szMoveSrc);
GetDirectory(szMoveSrc,szTempPath);
nDiff = _tcslen(szMoveSrc) - _tcslen(szTempPath);
pszSrcDirPointer = pszSrcDirPointer - nDiff;
_tcscpy(pszSrcDirPointer,_T(""));
pszDestDirPointer = pszDestDirPointer - nDiff;
_tcscpy(pszDestDirPointer,_T(""));
if(szMoveSrc[_tcslen(szMoveSrc) - 1] != _T('\\'))
_tcscat (szMoveSrc, _T("\\"));
if(szMoveDest[_tcslen(szMoveDest) - 1] != _T('\\'))
_tcscat (szMoveDest, _T("\\"));
pszDestDirPointer = szMoveDest + _tcslen(szMoveDest);
pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc);
_tcscpy(pszSrcDirPointer,_T("*.*"));
_tcscpy(pszDestDirPointer,_T("*.*"));
hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer);
if (hDestFile == INVALID_HANDLE_VALUE)
continue;
FirstTime = TRUE;
}
else
{
MoveStatus = TRUE; /* we moved everything so lets tell user about it */
RemoveDirectory(szMoveSrc);
}
continue;
}
/* if we find "." or ".." we'll skip them */
if (_tcscmp(findDestBuffer.cFileName,_T(".")) == 0 ||
_tcscmp(findDestBuffer.cFileName,_T("..")) == 0)
continue;
_tcscpy(pszSrcDirPointer, findDestBuffer.cFileName);
_tcscpy(pszDestDirPointer, findDestBuffer.cFileName);
if (IsExistingFile(szMoveSrc))
{
FoundFile = CopyFile(szMoveSrc, szMoveDest, FALSE);
if (!FoundFile) continue;
DeleteFile(szMoveSrc);
}
else
{
FindClose(hDestFile);
CreateDirectory(szMoveDest, NULL);
_tcscat(szMoveDest,_T("\\"));
_tcscat(szMoveSrc,_T("\\"));
nDirLevel++;
pszDestDirPointer = szMoveDest + _tcslen(szMoveDest);
pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc);
_tcscpy(pszSrcDirPointer,_T("*.*"));
_tcscpy(pszDestDirPointer,_T("*.*"));
hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer);
if (hDestFile == INVALID_HANDLE_VALUE)
{
FoundFile = FALSE;
continue;
}
FirstTime = TRUE;
}
}
/*bunch of checks to see if we the user wanted/wants
to really override the files*/
if((dwFlags & MOVE_OVER_NO) && IsExistingFile (szDestPath))
continue;
if(!(dwFlags & MOVE_OVER_YES) && IsExistingFile (szDestPath))
nOverwrite = Overwrite (szDestPath);
if (nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK)
continue;
if (nOverwrite == PROMPT_ALL)
dwFlags |= MOVE_OVER_YES;
ConOutPrintf (_T("%s => %s"), szSrcPath, szDestPath);
if ((dwFlags & MOVE_NOTHING))
continue;
/*delete the file first just to get ride of it
if it was already there*/
DeleteFile(szDestPath);
/*do the moving*/
if (MoveFileEx (szSrcPath, szDestPath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED))
LoadString(CMD_ModuleHandle, STRING_MOVE_ERROR1, szMsg, RC_STRING_MAX_SIZE);
else
LoadString(CMD_ModuleHandle, STRING_MOVE_ERROR2, szMsg, RC_STRING_MAX_SIZE);
ConOutPrintf(szMsg);
}
}
}
while (FindNextFile (hFile, &findBuffer));
FindClose (hFile);
if (MoveStatus)
LoadString(CMD_ModuleHandle, STRING_MOVE_ERROR1, szMsg, RC_STRING_MAX_SIZE);
else
LoadString(CMD_ModuleHandle, STRING_MOVE_ERROR2, szMsg, RC_STRING_MAX_SIZE);
ConOutPrintf(szMsg);
}
while ((!OnlyOneFile || dwMoveStatusFlags & MOVE_SRC_CURRENT_IS_DIR ) &&
!(dwMoveStatusFlags & MOVE_SOURCE_IS_DIR) &&
FindNextFile (hFile, &findBuffer));
FindClose (hFile);
freep (arg);
return 0;
}