home *** CD-ROM | disk | FTP | other *** search
- /*
- Auto: sc <file>
- Auto: Protect Move P ADD
- */
-
- /* $Revision Header built automatically *************** (do not edit) ************
- **
- ** © Copyright by GuntherSoft
- **
- ** File : SnakeSYS:CPrgs/Utils/Move.c
- ** Created on : Wednesday, 11.08.93 15:01:14
- ** Created by : Kai Iske
- ** Current revision : V37.11
- **
- **
- ** Purpose
- ** -------
- ** - Small move utility which supports wildcards and doesn`t use
- ** Rename() nor Copy() nor anything similar...
- **
- ** Revision V37.11
- ** ---------------
- ** created on Monday, 30.05.94 09:20:04 by Kai Iske. LogMessage :
- ** -*- changed on Donnerstag, 12.01.95 13:26:43 by Kai Iske. LogMessage :
- ** - Changed version numbering to official scheme
- ** -*- changed on Mittwoch, 11.01.95 11:04:23 by Kai Iske. LogMessage :
- ** - One couldn`t move the entire contents of a directory
- ** to a dir within that directory (eg. Move #? Dummy)
- ** -*- changed on Mittwoch, 11.01.95 11:03:55 by Kai Iske. LogMessage :
- ** - One couldn`t move directories, if the destination dirs
- ** already existed (eg. Move Dummy1 Dummy2 t:; if Dummy1
- ** and Dummy2 both existed in t:)
- ** -*- changed on Montag, 05.09.94 23:16:13 by Kai Iske. LogMessage :
- ** - OldWindow and HitMask vars weren`t preset to 0
- ** (Reported by : Christian Buchner)
- ** -*- created on Monday, 30.05.94 09:20:04 by Kai Iske. LogMessage :
- ** - When one issued something like this "Move #? dummy/",
- ** Move stopped when trying to move dummy to itself ;) Fixed
- **
- ** Revision V1.10
- ** --------------
- ** created on Sunday, 06.03.94 16:57:29 by Kai Iske. LogMessage :
- ** -*- created on Sunday, 06.03.94 16:57:29 by Kai Iske. LogMessage :
- ** - Move didn`t end up some operations with a "moved" string,
- ** thus leading to corrupted display
- ** (Reported by : Albert-Jan Brouwer)
- ** - One still couldn`t rename a directory
- ** (Reported by : Albert-Jan Brouwer)
- **
- ** Revision V1.9
- ** --------------
- ** created on Saturday, 26.02.94 14:15:24 by Kai Iske. LogMessage :
- ** -*- changed on Saturday, 26.02.94 14:29:20 by Kai Iske. LogMessage :
- ** - On recursive moves, Move will indent the output according to
- ** recursion depth. This is for better readability
- ** -*- changed on Saturday, 26.02.94 14:19:22 by Kai Iske. LogMessage :
- ** - Move will refuse to move a dir to itself now.
- ** -*- created on Saturday, 26.02.94 14:15:24 by Kai Iske. LogMessage :
- ** - One couldn`t move a dir to another dir on the same device
- **
- ** Revision V1.8
- ** --------------
- ** created on Sunday, 19.12.93 01:44:05 by Kai Iske. LogMessage :
- ** -*- changed on Sunday, 19.12.93 01:47:54 by Kai Iske. LogMessage :
- ** - Added PURE information to Doc, since Move really is pure
- ** (Suggested by : Albert-Jan Brouver)
- ** -*- changed on Sunday, 19.12.93 01:46:23 by Kai Iske. LogMessage :
- ** - Due to the move-renaming bug one couldn`t rename a dir
- ** an Assign was put on.
- ** (Reported by : Albert-Jan Brouver)
- ** -*- created on Sunday, 19.12.93 01:44:05 by Kai Iske. LogMessage :
- ** - Fixed move-renaming of directories.
- ** (Reported by : Albert-Jan Brouver)
- ** - Move had some severe problems recursively moving
- ** the contents of a directory
- **
- ** Revision V1.7
- ** --------------
- ** created on Saturday, 04.12.93 23:19:03 by Kai Iske. LogMessage :
- ** -*- changed on Saturday, 04.12.93 23:26:25 by Kai Iske. LogMessage :
- ** - Error while moving to a "device full" disk
- ** (Reported by : Chris Conger)
- ** -*- created on Saturday, 04.12.93 23:19:03 by Kai Iske. LogMessage :
- ** - FileName length-bug fixed
- ** (Reported by : Juergen Lang)
- ** - Recompiled using SAS 6.50
- ** - Stack usage reduced
- **
- ** Revision V1.6
- ** --------------
- ** created on Friday, 15.10.93 15:51:13 by Kai Iske. LogMessage :
- ** -*- changed on Saturday, 16.10.93 15:17:29 by Kai Iske. LogMessage :
- ** - Move got screwed up, when attempting to move a
- ** zero size file
- ** -*- changed on Friday, 15.10.93 16:03:35 by Kai Iske. LogMessage :
- ** - Added Buffer Keyword to specify the maximum buffer
- ** size for an inter device move. Normally Move would have used
- ** the max amount of available free memory in order to
- ** accomplish the move, or the size needed by the file...
- ** (Suggested by : Christof Damian)
- ** -*- created on Friday, 15.10.93 15:51:13 by Kai Iske. LogMessage :
- ** - One couldn`t rename a file using move, because the
- ** "destination" file was removed before doing the rename,
- ** ie. the source file was deleted.
- ** (Reported by : Chris Conger)
- **
- ** Revision V1.5
- ** --------------
- ** created on Tuesday, 05.10.93 01:42:53 by Kai Iske. LogMessage :
- ** -*- changed on Tuesday, 05.10.93 02:03:22 by Kai Iske. LogMessage :
- ** - Freed the FileInfoBlock _BEFORE_ setting the Bits, Comment
- ** etc. This lead to MungWall hits (of course it did)
- ** (Reported by Nico Francois)
- ** -*- created on Tuesday, 05.10.93 01:42:53 by Kai Iske. LogMessage :
- ** - Exidentially called one ExAll() without ED_SIZE
- ** This lead to some calls to DoTheMove without the Size set ;)
- ** (Reported by Karsten Weiss)
- **
- ** Revision V1.4
- ** --------------
- ** created on Friday, 01.10.93 16:55:15 by Kai Iske. LogMessage :
- ** -*- created on Friday, 01.10.93 16:55:15 by Kai Iske. LogMessage :
- ** - Now uses Rename() when source and dest are on the same
- ** device. This is faster ;) Why haven`t I thought of that
- ** earlier ??? ;)
- **
- ** Revision V1.3
- ** --------------
- ** created on Wednesday, 25.08.93 16:32:43 by Kai Iske. LogMessage :
- ** - UnLock Problem solved when doing recursive Dir-Moves
- ** This bug lead to "Object in use" error messages
- **
- ** Revision V1.2
- ** --------------
- ** created on Tuesday, 17.08.93 22:48:38 by Kai Iske. LogMessage :
- ** - Added CTRL-C checking
- ** - Added FORCE Flag in order to move read/deleteprotected or
- ** to overwrite a delete/writeprotected files
- **
- ** Revision V1.1
- ** --------------
- ** created on Monday, 16.08.93 22:53:34 by Kai Iske. LogMessage :
- ** - Added well known CLONE, DATES, COM, NOPRO,
- ** QUIET and NOREQ options also used by e.g. Rename
- **
- ** Revision V1.0
- ** --------------
- ** created on Wednesday, 11.08.93 15:01:14 by Kai Iske. LogMessage :
- ** --- Initial release ---
- **
- *********************************************************************************/
- #define REVISION "37.11"
- #define REVDATE "12.01.95"
- #define REVTIME "13:26:43"
- #define AUTHOR "Kai Iske"
- #define VERNUM 37
- #define REVNUM 11
-
- #include <string.h>
- #include <stdlib.h>
- #include <exec/types.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <exec/memory.h>
- #include <exec/execbase.h>
- #include <dos/exall.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
-
-
-
-
-
- /**********************************************************************/
- /* Defines for Flags */
- /**********************************************************************/
- #define CLONE 0x0001
- #define DATES 0x0002
- #define NOPRO 0x0004
- #define COM 0x0008
- #define QUIET 0x0010
- #define FORCE 0x0020
-
- #define WATCHSIGS SIGBREAKF_CTRL_C
-
-
-
- /**********************************************************************/
- /* Static char definitions */
- /**********************************************************************/
- static const char *Version = "$VER: Move "REVISION" ("REVDATE")\0";
- static const char *Template = "FROM/M,TO/A,CLONE/S,DATES/S,NOPRO/S,COM/S,QUIET/S,NOREQ/S,FORCE/S,BUFFER/N/K";
- enum {FROM_ARG, TO_ARG, CLONE_ARG, DATES_ARG, NOPRO_ARG, COM_ARG, QUIET_ARG, NOREQ_ARG, FORCE_ARG, BUFFER_ARG, LAST_ARG};
-
-
-
- /**********************************************************************/
- /* Prototypes */
- /**********************************************************************/
- int __saveds DoMove(void);
- static BOOL __stdargs DoTheMove(char *FromFile, char *ToPath, BOOL PatternFrom, BPTR OutHandle, LONG Type, ULONG Size, UWORD CopyFlags, LONG *HitMask, ULONG MaxBuffer, ULONG RecDepth);
- static BOOL __stdargs DoMoveFile(char *FromFile, char *ToPath, char *Buffer, BPTR OutHandle, ULONG Size, UWORD CopyFlags, LONG *HitMask, ULONG MaxBuffer);
-
-
-
- /**********************************************************************/
- /* Library bases */
- /**********************************************************************/
- struct DosLibrary *DOSBase = NULL;
-
-
-
- /**********************************************************************/
- /* The main program */
- /**********************************************************************/
- int __saveds DoMove(void)
- {
- struct FileInfoBlock *FIB;
- struct ExecBase *SysBase = *((struct ExecBase **)0x4L);
- struct Process *MyProc = (struct Process *)SysBase->ThisTask;
- struct RDArgs *RDArgs;
- struct ExAllControl *EAC;
- struct ExAllData *EAB, *EAD;
- APTR *Args,
- *OldWindow = NULL;
- BPTR DirLock,
- OutHandle;
- char **FromPtr;
- char *ToPtr;
- char *Pattern;
- char *PathName = NULL;
- char *Buffer = NULL;
- LONG HitMask = 0;
- UWORD NumFrom = 0,
- PatternType,
- CopyFlags = 0;
- ULONG MaxBuffer = 0;
- BOOL PatternFrom,
- GoOn = FALSE,
- Scanning;
-
-
-
-
- // Ignore startup from WB
-
- if(!(MyProc->pr_CLI))
- {
- struct Message *MyMsg;
-
- WaitPort(&MyProc->pr_MsgPort);
- MyMsg = GetMsg(&MyProc->pr_MsgPort);
- Disable();
- ReplyMsg(MyMsg);
- return(10);
- }
-
- // Do the wild thing
-
- if((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)))
- {
- // Allocate buffers
-
- if((Pattern = AllocVec(1024, MEMF_CLEAR)) && (PathName = AllocVec(1024, MEMF_CLEAR)) && (Buffer = AllocVec(1024, MEMF_CLEAR)))
- {
- if((FIB = AllocVec(sizeof(struct FileInfoBlock), MEMF_CLEAR)))
- {
- // Get buffer for ReadArgs()
-
- if((Args = AllocVec((LAST_ARG * sizeof(ULONG)), MEMF_CLEAR)))
- {
- // Get structure for ExAll()
-
- if((EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
- {
- // Get buffer for ExAll()
-
- if((EAB = AllocVec((sizeof(struct ExAllData)*20), MEMF_CLEAR)))
- {
- // Parse commandline
-
- if((RDArgs = ReadArgs((char *)Template, (LONG *)Args, NULL)))
- {
- // From and to really there ??
-
- if(Args[FROM_ARG] && Args[TO_ARG])
- {
- // A O.K. so far
-
- GoOn = TRUE;
-
- // Get output handle
-
- OutHandle = Output();
-
- // Get Flags
-
- if(Args[CLONE_ARG])
- CopyFlags |= CLONE;
- if(Args[DATES_ARG])
- CopyFlags |= DATES;
- if(Args[NOPRO_ARG])
- CopyFlags |= NOPRO;
- if(Args[COM_ARG])
- CopyFlags |= COM;
- if(Args[QUIET_ARG])
- CopyFlags |= QUIET;
- if(Args[FORCE_ARG])
- CopyFlags |= FORCE;
- if(Args[BUFFER_ARG])
- MaxBuffer = *((ULONG *)Args[BUFFER_ARG]) * 1024;
-
- // Check for NOREQ Option
-
- if(Args[NOREQ_ARG])
- {
- OldWindow = MyProc->pr_WindowPtr;
- MyProc->pr_WindowPtr = (void *)(-1L);
- }
-
- // Get pointers to Files
-
- FromPtr = (char **)Args[FROM_ARG];
- ToPtr = (char *)Args[TO_ARG];
-
- // Count FROM entries
-
- while(*FromPtr++)
- NumFrom++;
-
- // Restore FromPtr
-
- FromPtr = (char **)Args[FROM_ARG];
-
- // Set pattern if there are more than 1
- // FROM files or if the only FROM file
- // is a pattern
-
- if(NumFrom > 1)
- PatternFrom = TRUE;
- else
- PatternFrom = ParsePatternNoCase(*FromPtr, Pattern, 1024);
-
- // If a pattern is used, check
- // whether the dest really is a dir
-
- if(PatternFrom)
- {
- // Try to obtain a lock
-
- if((DirLock = Lock(ToPtr, ACCESS_READ)))
- {
- // Check file
-
- if(Examine(DirLock, FIB))
- {
- // Get type of destination entry
-
- GoOn = (FIB->fib_DirEntryType >= 0);
-
- // If it`s not a directory (multiple files are to be moved)
- // issue an error
-
- if(!GoOn)
- FPuts(OutHandle, "\nMove : Multiple files may not be moved to a single file\n");
- }
- else
- {
- // Examine() failed -> Abort
-
- GoOn = FALSE;
- PrintFault(IoErr(), "\nMove ");
- }
-
- // Unlock CheckDir
-
- UnLock(DirLock);
- }
- else
- {
- // If lock failed issue an error
-
- PrintFault(IoErr(), "\nMove ");
- GoOn = FALSE;
- }
- }
-
-
-
- // Loop for all source files
-
- while(NumFrom && GoOn)
- {
- // Check for CTRL-C
-
- if(GoOn)
- HitMask = CheckSignal(WATCHSIGS);
-
- if(!HitMask && GoOn)
- {
- // Check if this source is a pattern
-
- strcpy(Buffer, FilePart(*FromPtr));
- strupr(Buffer);
- PatternType = ParsePatternNoCase(Buffer, Pattern, 1024);
-
- // It is a pattern
-
- if(PatternType == 1)
- {
- // Create name of source
-
- strcpy(Buffer, *FromPtr);
- *PathPart(Buffer) = '\0';
-
- // Get Lock for Source - Directory
-
- if((DirLock = Lock(Buffer, ACCESS_READ)))
- {
- // Setup ExAllControl-Structure
-
- EAC->eac_LastKey = 0L;
- EAC->eac_MatchString = Pattern;
- EAC->eac_MatchFunc = NULL;
-
- do
- {
- // Check for CTRL-C
-
- if(GoOn)
- HitMask = CheckSignal(WATCHSIGS);
-
- if(HitMask)
- GoOn = FALSE;
-
- // Scan directory
-
- Scanning = ExAll(DirLock, EAB, (20*sizeof(struct ExAllData)), ED_SIZE, EAC);
-
- // Issue Error
-
- if(GoOn && (!Scanning) && (IoErr() != ERROR_NO_MORE_ENTRIES))
- {
- PrintFault(IoErr(), "\nMove ");
- GoOn = FALSE;
- }
-
- // End of Dir reached
-
- if(EAC->eac_Entries == 0)
- Scanning = FALSE;
- else if(GoOn)
- {
- EAD = EAB;
-
- do
- {
- // Check for CTRL-C
-
- if(GoOn)
- HitMask = CheckSignal(WATCHSIGS);
-
- if(!HitMask && GoOn)
- {
- // Create filename for this file to be moved
-
- strcpy(PathName, *FromPtr);
- *PathPart(PathName) = '\0';
- AddPart(PathName, EAD->ed_Name, 1024);
-
- // Move file
-
- GoOn = DoTheMove(PathName, ToPtr, TRUE, OutHandle, EAD->ed_Type, EAD->ed_Size, CopyFlags, &HitMask, MaxBuffer, 1);
-
- EAD = EAD->ed_Next;
- }
- else
- GoOn = FALSE;
-
- } while(EAD && GoOn);
- }
- } while(Scanning);
-
- // Unlock source directory
-
- UnLock(DirLock);
- }
- else
- {
- // Issue error, if dir could not be locked
-
- PrintFault(IoErr(), "\nMove ");
- GoOn = FALSE;
- }
- }
- // No pattern
-
- else if(PatternType == 0)
- {
- // Try to lock source file/dir
-
- if((DirLock = Lock(*FromPtr, ACCESS_READ)))
- {
- // Examine this lock
-
- if(Examine(DirLock, FIB))
- {
- // Unlock directory and do the move
-
- UnLock(DirLock);
- GoOn = DoTheMove(*FromPtr, ToPtr, TRUE, OutHandle, FIB->fib_DirEntryType, FIB->fib_Size, CopyFlags, &HitMask, MaxBuffer, 1);
- }
- else
- {
- // Issue error on failed Examine()
-
- PrintFault(IoErr(), "\nMove ");
- GoOn = FALSE;
- UnLock(DirLock);
- }
- }
- else
- {
- // No Lock() no more moves
-
- PrintFault(IoErr(), "\nMove ");
- GoOn = FALSE;
- }
- }
-
- // Error condition
-
- else
- {
- PrintFault(IoErr(), "\nMove ");
- GoOn = FALSE;
- }
-
- NumFrom--;
- FromPtr++;
- }
- else
- GoOn = FALSE;
- }
- }
-
- // Free ReadArgs
-
- FreeArgs(RDArgs);
- }
- else
- PrintFault(IoErr(), "\nMove ");
-
- // Free ExAll-Buffer
-
- FreeVec(EAB);
- }
- else
- PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
-
- // Free ExAllControl Structure
-
- FreeDosObject(DOS_EXALLCONTROL, (void *)EAC);
- }
- else
- PrintFault(IoErr(), "\nMove ");
-
- // Free Argument Buffer
-
- FreeVec(Args);
- }
- else
- PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
-
- FreeVec(FIB);
- }
- else
- PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
- }
- else
- PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
-
-
- // Free allocated buffers
-
- if(Pattern)
- FreeVec(Pattern);
-
- if(PathName)
- FreeVec(PathName);
-
- if(Buffer)
- FreeVec(Buffer);
-
-
- // Check for Abort-Signals
-
- if(HitMask && !(CopyFlags & QUIET))
- {
- // Display appropriate message
-
- if(HitMask & SIGBREAKF_CTRL_C)
- FPuts(OutHandle, "\nMove ^C...\n");
- }
-
- // Close DOSLibrary
-
- CloseLibrary((struct Library *)DOSBase);
- }
-
- // Restore old window pointer (if any)
-
- if(OldWindow)
- MyProc->pr_WindowPtr = OldWindow;
-
-
- // Depending on this flag return appropriate return code
-
- if(GoOn)
- return(0);
- else
- return(10);
- }
-
-
-
-
- /**********************************************************************/
- /* Do the move */
- /**********************************************************************/
- static BOOL __stdargs DoTheMove(char *FromFile, char *ToPath, BOOL PatternFrom, BPTR OutHandle, LONG Type, ULONG Size, UWORD CopyFlags, LONG *HitMask, ULONG MaxBuffer, ULONG RecDepth)
- {
- struct ExAllControl *EAC;
- struct ExAllData *EAB, *EAD;
- char *NewDir;
- char *Buffer = NULL;
- char *ToDir = NULL;
- char *DispBuff = NULL;
- UWORD Len;
- BPTR DirLock;
- BOOL RetVal = TRUE,
- Scanning,
- DoRename = FALSE,
- MoveDirToSame = FALSE,
- Skipped = FALSE;
-
-
- // Try to allocate buffers
-
- if((NewDir = AllocVec(1024, MEMF_CLEAR)) && (Buffer = AllocVec(1024, MEMF_CLEAR)) && (ToDir = AllocVec(1024, MEMF_CLEAR)) && (DispBuff = AllocVec(1024, MEMF_CLEAR)))
- {
- // Is it a directory ???
- // If yes, recursively loop for all entries within dir
-
- if(Type >= 0)
- {
- strcpy(Buffer, FromFile);
-
- // Get length of from name
-
- Len = strlen(Buffer);
-
- // Really got a from name ?!?
-
- if(Len)
- {
- if(Buffer[Len - 1] == '/')
- Buffer[Len - 1] = '\0';
-
- // Copy dest name to buffer
-
- strcpy(NewDir, ToPath);
-
- // Check for dir moving to itself...
- // ...and for renaming
-
- if((DirLock = Lock(Buffer, ACCESS_READ)))
- {
- BPTR TestLock;
-
- if((TestLock = Lock(NewDir, ACCESS_READ)))
- {
- // Working on same volume?
-
- DoRename = (SameLock(DirLock, TestLock) == LOCK_SAME_VOLUME);
-
- // Renaming a directory ???
-
- MoveDirToSame = (SameLock(DirLock, TestLock) == LOCK_SAME);
-
- UnLock(TestLock);
- }
-
- UnLock(DirLock);
- }
-
-
- // Ok, we are to move
- // If a pattern is used print the name of the dir to be moved
-
- if(PatternFrom && !(CopyFlags & QUIET))
- {
- int i;
-
- // Prepend number of spaces according to recursion depth
-
- for(i = 0; i < RecDepth; i++)
- DispBuff[i] = ' ';
- DispBuff[i] = '\0';
-
- strcat(DispBuff, FromFile);
- strcat(DispBuff, "...");
- Write(OutHandle, " ", 1);
- Write(OutHandle, DispBuff, strlen(DispBuff));
- }
-
-
- // Destination directory available ???
- // If so, we are to move to that directory
- // Otherwise, we`ll simply rename
-
- if((DirLock = Lock(NewDir, ACCESS_READ)))
- {
- UnLock(DirLock);
-
- // Add name of from directory
-
- if(!MoveDirToSame)
- AddPart(NewDir, FilePart(Buffer), 1024);
- }
-
-
- // Simple rename; no cross-device move ?!?
-
- if(DoRename)
- {
- BOOL DoTheRename = TRUE;
-
- // Trying to rename a directory?
- // Only allowed when not in pattern or multimode
-
- if(MoveDirToSame)
- DoTheRename = !PatternFrom;
-
- // Still rename the directory?
-
- if(DoTheRename)
- {
- BPTR TestLock;
-
- // Destination is already there?
- // If so, only move contents
-
- if((TestLock = Lock(NewDir, ACCESS_READ)))
- {
- DoRename = FALSE;
- UnLock(TestLock);
- }
- else
- {
- // Do the rename
-
- if(!Rename(Buffer, NewDir))
- {
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
- }
- }
- else
- Skipped = TRUE;
- }
-
- if(!DoRename)
- {
- // Clone directory name of source
-
- strcpy(ToDir, Buffer);
-
- // Try to lock directory or
- // create it, if not existent
-
- if(!(DirLock = Lock(NewDir, ACCESS_READ)))
- {
- if((DirLock = CreateDir(NewDir)) && PatternFrom && !(CopyFlags & QUIET))
- Write(OutHandle, " [created]...", 13);
- }
-
- // Got the destination directory ???
-
- if(DirLock)
- {
- // Unlock Directory
-
- UnLock(DirLock);
-
- // Lock sourcedirectory
-
- if((DirLock = Lock(Buffer, ACCESS_READ)))
- {
- // Get ExAll Control for recursive directory search
-
- if((EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
- {
- // Allocate buffer for move
-
- if((EAB = AllocVec((20*sizeof(struct ExAllData)), MEMF_CLEAR)))
- {
- EAC->eac_LastKey = 0L;
- EAC->eac_MatchString = NULL;
- EAC->eac_MatchFunc = NULL;
-
- do
- {
- // Check for CTRL-C
-
- if(RetVal)
- (*HitMask) = CheckSignal(WATCHSIGS);
-
- if((*HitMask))
- RetVal = FALSE;
-
- // Scan directory for entries
-
- Scanning = ExAll(DirLock, EAB, (20*sizeof(struct ExAllData)), ED_SIZE, EAC);
-
- // Check for an error
-
- if(RetVal && (!Scanning) && (IoErr() != ERROR_NO_MORE_ENTRIES))
- {
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
-
- // End of Dir reached
-
- if(EAC->eac_Entries == 0)
- Scanning = FALSE;
- else if(RetVal)
- {
- EAD = EAB;
-
- do
- {
- // Check for CTRL-C
-
- if(RetVal)
- (*HitMask) = CheckSignal(WATCHSIGS);
-
- if(!(*HitMask) && RetVal)
- {
- // Create filename of source
-
- strcpy(Buffer, FromFile);
- AddPart(Buffer, EAD->ed_Name, 1024);
-
- // And start recursion
-
- RetVal = DoTheMove(Buffer, NewDir, FALSE, OutHandle, EAD->ed_Type, EAD->ed_Size, CopyFlags, HitMask, MaxBuffer, RecDepth + 1);
-
- // Loop for all entries
-
- EAD = EAD->ed_Next;
- }
- else
- RetVal = FALSE;
-
- } while(EAD && RetVal);
- }
- } while(Scanning);
-
- // Free ExAll Buffer
-
- FreeVec(EAB);
- }
- else
- {
- PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
- RetVal = FALSE;
- }
-
- // Free ExAllControl Structure
-
- FreeDosObject(DOS_EXALLCONTROL, EAC);
- }
- else
- {
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
-
- UnLock(DirLock);
- }
- else
- {
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
- }
- else
- {
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
- }
-
- // Ok, this dir was moved (no rename), so remove it
-
- if(RetVal && !DoRename)
- {
- // With force mode set on,
- // First make dir deletable
-
- if(CopyFlags & FORCE)
- SetProtection(ToDir, ~(FIBF_OTR_WRITE|FIBF_OTR_DELETE|FIBF_WRITE|FIBF_DELETE));
-
- // Delete directory
-
- if(!DeleteFile(ToDir))
- {
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
- }
-
- // Display "moved" message
-
- if(PatternFrom && RetVal && !(CopyFlags & QUIET))
- {
- if(!Skipped)
- FPuts(OutHandle, " moved\n");
- else
- FPuts(OutHandle, " skipped\n");
- }
- }
- }
- else
- {
- // Ok, we are to move
- // If a pattern is used print the name of the file to be moved
-
- if(PatternFrom && !(CopyFlags & QUIET))
- {
- int i;
-
- // Prepend number of spaces according to recursion depth
-
- for(i = 0; i < RecDepth; i++)
- DispBuff[i] = ' ';
- DispBuff[i] = '\0';
-
- strcat(DispBuff, FromFile);
- strcat(DispBuff, "...");
- Write(OutHandle, " ", 1);
- Write(OutHandle, DispBuff, strlen(DispBuff));
- }
-
- // On a plain file -> Simply move it
-
- RetVal = DoMoveFile(FromFile, ToPath, Buffer, OutHandle, Size, CopyFlags, HitMask, MaxBuffer);
-
- // If there was a pattern (or a single directory)
- // end the Move string
-
- if(PatternFrom && RetVal && !(CopyFlags & QUIET))
- {
- if(!Skipped)
- FPuts(OutHandle, " moved\n");
- else
- FPuts(OutHandle, " skipped\n");
- }
- }
- }
- else
- {
- PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
- RetVal = FALSE;
- }
-
- // De-Allocate buffers
-
- if(NewDir)
- FreeVec(NewDir);
-
- if(Buffer)
- FreeVec(Buffer);
-
- if(ToDir)
- FreeVec(ToDir);
-
- if(DispBuff)
- FreeVec(DispBuff);
-
- // Return Code
-
- return(RetVal);
- }
-
-
-
-
-
-
-
-
- /**********************************************************************/
- /* Physically move a file */
- /**********************************************************************/
- static BOOL __stdargs DoMoveFile(char *FromFile, char *ToPath, char *Buffer, BPTR OutHandle, ULONG Size, UWORD CopyFlags, LONG *HitMask, ULONG MaxBuffer)
- {
- struct FileInfoBlock *FIB;
- BPTR InFile,
- OutFile;
- char *DestName;
- APTR CopyBuffer;
- ULONG ReadSize,
- AvailSize;
- LONG InKey = -1,
- OutKey = -1;
- BOOL RetVal = TRUE,
- ErrCpy = FALSE,
- LoopCpy = TRUE,
- DoRename = FALSE,
- RemoveFirst = FALSE;
-
-
- // Allocate buffer for Destination name
-
- if(!(DestName = AllocVec(1024, MEMF_CLEAR)))
- {
- PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
- return(FALSE);
- }
-
- if((FIB = AllocVec(sizeof(struct FileInfoBlock), MEMF_CLEAR)))
- {
-
- strcpy(DestName, ToPath);
-
- // Check, if destfile already exists
- // If so, check if it`s a dir.
- // Yes -> Copy with sourcename
- // No -> Copy with given name
-
- if((OutFile = Lock(DestName, ACCESS_READ)))
- {
- if(Examine(OutFile, FIB))
- {
- // If dest is a directory move with source name
-
- if(FIB->fib_DirEntryType >= 0)
- AddPart(DestName, FilePart(FromFile), 1024);
- else
- {
- OutKey = ((struct FileLock *)BADDR(OutFile))->fl_Key;
- RemoveFirst = TRUE;
- }
- }
- else
- {
- // No examine -> Use source filename
-
- AddPart(DestName, FilePart(FromFile), 1024);
- }
-
- UnLock(OutFile);
- }
-
- // Try to lock input file
-
- if((InFile = Lock(FromFile, ACCESS_READ)))
- {
- // Get DiskBlock for inputfile
-
- InKey = ((struct FileLock *)BADDR(InFile))->fl_Key;
-
- // Get old protection bits, comment and filedate
-
- if(Examine(InFile, FIB))
- {
- // In Force mode -> Force read and delete permissons
- // for input file
-
- if(CopyFlags & FORCE)
- SetProtection(FromFile, ~(FIBF_OTR_READ|FIBF_OTR_DELETE|FIBF_READ|FIBF_DELETE));
- }
- else
- {
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
-
- // If so, unlock
-
- UnLock(InFile);
- }
- else
- {
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
-
- // Can we possibly simple rename the file?
-
- if((InFile = Lock(FromFile, ACCESS_READ)))
- {
- if((OutFile = Lock(ToPath, ACCESS_READ)))
- {
- DoRename = (SameLock(InFile, OutFile) == LOCK_SAME_VOLUME);
-
- UnLock(OutFile);
- }
-
- UnLock(InFile);
- }
-
- // No Rename -> Do the right move ;)
-
- if(!DoRename)
- {
- // Open Input file
-
- if(RetVal && (InFile = Open(FromFile, MODE_OLDFILE)))
- {
- // Outfile already there ??? and in force mode ???
-
- if((CopyFlags & FORCE) && ((OutFile = Lock(DestName, ACCESS_READ))))
- {
- // Force delete and write permissons
-
- UnLock(OutFile);
- SetProtection(DestName, ~(FIBF_OTR_WRITE|FIBF_OTR_DELETE|FIBF_WRITE|FIBF_DELETE));
- }
-
-
- // Open Output file
-
- if((OutFile = Open(DestName, MODE_NEWFILE)))
- {
- // Is there any data within the file ???
-
- if(Size)
- {
- // Get available size of memory
- // or take the user`s buffer size into account
-
- AvailSize = (MaxBuffer != 0) ? MaxBuffer : (AvailMem(MEMF_LARGEST) - 102400);
- Size = (Size > AvailSize) ? AvailSize : Size;
-
- // Loop till we get a buffer
-
- while(Size && !(CopyBuffer = AllocVec(Size, MEMF_CLEAR)))
- Size -= 1024;
-
-
- if(CopyBuffer)
- {
- // Loop for portions of the source file
-
- while(RetVal && LoopCpy)
- {
- // Check for CTRL-C
-
- if(RetVal)
- (*HitMask) = CheckSignal(WATCHSIGS);
-
- if(!(*HitMask) && RetVal)
- {
- // Read part of file
-
- if((ReadSize = Read(InFile, CopyBuffer, Size)) > 0)
- {
- // And write it back
-
- if(Write(OutFile, CopyBuffer, ReadSize) == -1)
- {
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- ErrCpy = TRUE;
- }
- }
- else
- {
- // EOF ??? -> End copy
-
- if(ReadSize == 0)
- LoopCpy = FALSE;
- else
- {
- // Otherwise issue error
-
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- ErrCpy = TRUE;
- }
- }
- }
- else
- RetVal = FALSE;
- }
-
- FreeVec(CopyBuffer);
- }
- else
- {
- PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
- RetVal = FALSE;
- ErrCpy = TRUE;
- }
- }
-
- Close(OutFile);
- }
- else
- {
- // Issue error
-
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
- // Close InFile
-
- Close(InFile);
- }
- else
- {
- // Issue error
-
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
- }
- else
- {
- // If RemoveFirst is not set, check again ;)
-
- if(!RemoveFirst)
- {
- if((OutFile = Lock(DestName, ACCESS_READ)))
- {
- if(Examine(OutFile, FIB))
- {
- // If dest is a file, delete first
-
- if(FIB->fib_DirEntryType < 0)
- {
- // Get Disk block of dest file
-
- OutKey = ((struct FileLock *)BADDR(OutFile))->fl_Key;
- RemoveFirst = TRUE;
- }
- }
- UnLock(OutFile);
- }
- }
-
- // Check if only a rename should be accomplished
-
- if(InKey != -1 && OutKey != -1)
- {
- if(InKey == OutKey)
- RemoveFirst = FALSE;
- }
-
- // In Rename() mode, the destination has to be removed first
-
- if(RemoveFirst)
- {
- // If dest file is protected check for FORCE flag
-
- if(CopyFlags & FORCE)
- SetProtection(DestName, ~(FIBF_OTR_WRITE|FIBF_OTR_DELETE|FIBF_WRITE|FIBF_DELETE));
-
- if(!DeleteFile(DestName))
- {
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
- }
-
- if(RetVal)
- {
- // Now try to "rename" the file
-
- if(!Rename(FromFile, DestName))
- {
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
- }
- }
-
- // Error while copying ?? -> Remove Dest file
-
- if(ErrCpy)
- {
- FPuts(OutHandle, "\nMove : Error while moving; destination removed.\n");
- DeleteFile(DestName);
- }
-
- // No Error -> Remove Source file
-
- if(RetVal && !ErrCpy)
- {
- if(!DoRename && !(RetVal = DeleteFile(FromFile)))
- PrintFault(IoErr(), "\nMove ");
- else
- {
- // Set bits etc. as requested
-
- if((CopyFlags & CLONE) || (CopyFlags & DATES))
- SetFileDate(DestName, &FIB->fib_Date);
-
- if((CopyFlags & CLONE) || (CopyFlags & COM))
- SetComment(DestName, FIB->fib_Comment);
-
- if(((CopyFlags & CLONE) && !(CopyFlags & NOPRO)) || (!(CopyFlags & CLONE) && !(CopyFlags & NOPRO)))
- SetProtection(DestName, FIB->fib_Protection);
- }
- }
-
- // Free FileInfo Block
-
- FreeVec(FIB);
- }
- else
- {
- PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
- RetVal = FALSE;
- }
-
- // Free buffer for destination name
-
- FreeVec(DestName);
-
- return(RetVal);
- }
-