home *** CD-ROM | disk | FTP | other *** search
- /*
- Auto: smake Move
- */
-
- /* $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 : V1.3
- **
- **
- ** Purpose
- ** -------
- ** - Small move utility which supports wildcards and doesn`t use
- ** Rename() nor Copy() nor anything similar...
- **
- ** 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 "1.3"
- #define REVDATE "25.08.93"
- #define REVTIME "16:32:43"
- #define AUTHOR "Kai Iske"
- #define VERNUM 1
- #define REVNUM 3
-
- #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>
-
-
-
- /**********************************************************************/
- /* 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 char *Version = "$VER: Move "REVISION" ("REVDATE")\0";
- static char *Template = "FROM/M,TO/A,CLONE/S,DATES/S,NOPRO/S,COM/S,QUIET/S,NOREQ/S,FORCE/S";
- enum {FROM_ARG, TO_ARG, CLONE_ARG, DATES_ARG, NOPRO_ARG, COM_ARG, QUIET_ARG, NOREQ_ARG, FORCE_ARG, LAST_ARG};
-
-
-
- /**********************************************************************/
- /* Prototypes */
- /**********************************************************************/
- int __saveds DoMove(void);
- BOOL DoTheMove(char *FromFile, char *ToPath, BOOL PatternFrom, BPTR OutHandle, struct DOSBase *DOSBase, LONG Type, LONG Size, UWORD CopyFlags, LONG *HitMask);
- BOOL DoMoveFile(char *FromFile, char *ToPath, char *Buffer, BPTR OutHandle, struct DOSBase *DOSBase, LONG Size, UWORD CopyFlags, LONG *HitMask);
-
-
- /**********************************************************************/
- /* The main program */
- /**********************************************************************/
- int __saveds DoMove(void)
- {
- struct FileInfoBlock *FIB;
- struct ExecBase *SysBase = *((struct ExecBase **)0x4L);
- struct DOSBase *DOSBase;
- struct Process *MyProc = (struct Process *)SysBase->ThisTask;
- struct RDArgs *RDArgs;
- struct ExAllControl *EAC;
- struct ExAllData *EAB, *EAD;
- APTR *Args,
- *OldWindow;
- BPTR DirLock,
- OutHandle;
- char **FromPtr;
- char *ToPtr;
- char Pattern[256];
- char PathName[256];
- char Buffer[256];
- LONG HitMask;
- UWORD NumFrom = 0, PatternType, CopyFlags = 0;
- BOOL PatternFrom, GoOn = TRUE, 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(0);
- }
-
- // Do the wild thing
-
- if((DOSBase = (struct DOSBase *)OpenLibrary("dos.library", 37)))
- {
- 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(Template, (ULONG *)Args, NULL)))
- {
- // From and to really there ??
-
- if(Args[FROM_ARG] && Args[TO_ARG])
- {
- 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;
-
- // 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, 256);
-
- // 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, 256);
-
- // 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_TYPE, 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)
- {
- // Createfilename for this file to be moved
-
- strcpy(PathName, *FromPtr);
- *PathPart(PathName) = '\0';
- AddPart(PathName, EAD->ed_Name, 256);
-
- // Move file
-
- if((GoOn = DoTheMove(PathName, ToPtr, TRUE, OutHandle, DOSBase, EAD->ed_Type, EAD->ed_Size, CopyFlags, &HitMask)) && (EAD->ed_Type > 0))
- {
- // Delete directory after a succesful move
-
- if(!(GoOn = DeleteFile(PathName)))
- PrintFault(IoErr(), "\nMove ");
- }
-
- 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);
- if((GoOn = DoTheMove(*FromPtr, ToPtr, TRUE, OutHandle, DOSBase, FIB->fib_DirEntryType, FIB->fib_Size, CopyFlags, &HitMask)) && (FIB->fib_DirEntryType > 0))
- {
- // Delete dir after a succesfull move
-
- if(!(GoOn = DeleteFile(*FromPtr)))
- PrintFault(IoErr(), "\nMove ");
- }
- }
- 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 ");
-
- // 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 */
- /**********************************************************************/
- BOOL DoTheMove(char *FromFile, char *ToPath, BOOL PatternFrom, BPTR OutHandle, struct DOSBase *DOSBase, LONG Type, LONG Size, UWORD CopyFlags, LONG *HitMask)
- {
- struct ExAllControl *EAC;
- struct ExAllData *EAB, *EAD;
- char NewDir[256];
- char Buffer[256];
- UWORD Len;
- BPTR DirLock;
- BOOL RetVal = TRUE, Scanning;
-
- // If a pattern is used print the name of the file to be moved
-
- if(PatternFrom && !(CopyFlags & QUIET))
- {
- strcpy(Buffer, FromFile);
- strcat(Buffer, "...");
- Write(OutHandle, " ", 1);
- Write(OutHandle, Buffer, strlen(Buffer));
- }
-
- // 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);
- if(Len)
- {
- if(Buffer[Len - 1] == '/')
- Buffer[Len - 1] = '\0';
-
- // Copy dest name to buffer
-
- strcpy(NewDir, ToPath);
-
- // Add name of from directory
-
- AddPart(NewDir, FilePart(Buffer), 256);
-
- // 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, 256);
-
- // And start recursion
-
- if((RetVal = DoTheMove(Buffer, NewDir, FALSE, OutHandle, DOSBase, EAD->ed_Type, EAD->ed_Size, CopyFlags, HitMask)) && (EAD->ed_Type > 0))
- {
- // if file moved was a dir, delete it
-
- if(!(RetVal = DeleteFile(Buffer)))
- PrintFault(IoErr(), "\nMove ");
- }
-
- // 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;
- }
- }
- }
- else
- {
- // On a plain file -> Simply move it
-
- RetVal = DoMoveFile(FromFile, ToPath, Buffer, OutHandle, DOSBase, Size, CopyFlags, HitMask);
- }
-
- // If there was a pattern (or a single directory)
- // end the Move string
-
- if(PatternFrom && RetVal && !(CopyFlags & QUIET))
- FPuts(OutHandle, " moved\n");
-
- // Return Code
-
- return(RetVal);
- }
-
-
-
-
-
- /**********************************************************************/
- /* Ein File wirklich moven */
- /**********************************************************************/
- BOOL DoMoveFile(char *FromFile, char *ToPath, char *Buffer, BPTR OutHandle, struct DOSBase *DOSBase, LONG Size, UWORD CopyFlags, LONG *HitMask)
- {
- struct FileInfoBlock *FIB;
- BPTR InFile, OutFile;
- APTR CopyBuffer;
- char DestName[256];
- LONG AvailSize, ReadSize;
- BOOL RetVal = TRUE, ErrCpy = FALSE, LoopCpy = TRUE;
-
- 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), 256);
- }
- else
- {
- // No examine -> Use source filename
-
- AddPart(DestName, FilePart(FromFile), 256);
- }
-
- UnLock(OutFile);
- }
-
- // Try to lock input file
-
- if((InFile = Lock(FromFile, ACCESS_READ)))
- {
- // 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;
- }
-
- // 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)))
- {
- // Get available size of memory
-
- AvailSize = AvailMem(MEMF_LARGEST);
- 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, Size) == -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;
- }
-
- // Free Copy buffer
-
- FreeVec(CopyBuffer);
- }
- else
- {
- // Issue error
-
- PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
- RetVal = FALSE;
- ErrCpy = TRUE;
- }
-
- // Close outfile
-
- Close(OutFile);
- }
- else
- {
- // Issue error
-
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
- // Close InFile
-
- Close(InFile);
- }
- else
- {
- // Issue error
-
- PrintFault(IoErr(), "\nMove ");
- RetVal = FALSE;
- }
-
- // Free FileInfo Block
-
- FreeVec(FIB);
- }
- else
- {
- PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
- RetVal = FALSE;
- }
-
- // Error while copying ?? -> Remove Dest file
-
- if(ErrCpy)
- DeleteFile(DestName);
-
- // No Error -> Remove Source file
-
- if(RetVal && !ErrCpy)
- {
- if(!(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);
- }
- }
-
-
- return(RetVal);
- }
-