home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / util / cli / move / move.c < prev    next >
C/C++ Source or Header  |  1995-01-13  |  33KB  |  1,338 lines

  1. /*
  2. Auto:        sc <file>
  3. Auto:        Protect Move P ADD
  4. */
  5.  
  6. /* $Revision Header built automatically *************** (do not edit) ************
  7. **
  8. ** © Copyright by GuntherSoft
  9. **
  10. ** File             : SnakeSYS:CPrgs/Utils/Move.c
  11. ** Created on       : Wednesday, 11.08.93 15:01:14
  12. ** Created by       : Kai Iske
  13. ** Current revision : V37.11
  14. **
  15. **
  16. ** Purpose
  17. ** -------
  18. **   - Small move utility which supports wildcards and doesn`t use
  19. **     Rename() nor Copy() nor anything similar...
  20. **
  21. ** Revision V37.11
  22. ** ---------------
  23. ** created on Monday, 30.05.94 09:20:04  by  Kai Iske.   LogMessage :
  24. **  -*-  changed on Donnerstag, 12.01.95 13:26:43  by  Kai Iske.   LogMessage :
  25. **   - Changed version numbering to official scheme
  26. **  -*-  changed on Mittwoch, 11.01.95 11:04:23  by  Kai Iske.   LogMessage :
  27. **   - One couldn`t move the entire contents of a directory
  28. **     to a dir within that directory (eg. Move #? Dummy)
  29. **  -*-  changed on Mittwoch, 11.01.95 11:03:55  by  Kai Iske.   LogMessage :
  30. **   - One couldn`t move directories, if the destination dirs
  31. **     already existed (eg. Move Dummy1 Dummy2 t:; if Dummy1
  32. **     and Dummy2 both existed in t:)
  33. **  -*-  changed on Montag, 05.09.94 23:16:13  by  Kai Iske.   LogMessage :
  34. **   - OldWindow and HitMask vars weren`t preset to 0
  35. **     (Reported by : Christian Buchner)
  36. **  -*-  created on Monday, 30.05.94 09:20:04  by  Kai Iske.   LogMessage :
  37. **   - When one issued something like this "Move #? dummy/",
  38. **     Move stopped when trying to move dummy to itself ;) Fixed
  39. **
  40. ** Revision V1.10
  41. ** --------------
  42. ** created on Sunday, 06.03.94 16:57:29  by  Kai Iske.   LogMessage :
  43. **  -*-  created on Sunday, 06.03.94 16:57:29  by  Kai Iske.   LogMessage :
  44. **   - Move didn`t end up some operations with a "moved" string,
  45. **     thus leading to corrupted display
  46. **     (Reported by : Albert-Jan Brouwer)
  47. **   - One still couldn`t rename a directory
  48. **     (Reported by : Albert-Jan Brouwer)
  49. **
  50. ** Revision V1.9
  51. ** --------------
  52. ** created on Saturday, 26.02.94 14:15:24  by  Kai Iske.   LogMessage :
  53. **  -*-  changed on Saturday, 26.02.94 14:29:20  by  Kai Iske.   LogMessage :
  54. **   - On recursive moves, Move will indent the output according to
  55. **     recursion depth. This is for better readability
  56. **  -*-  changed on Saturday, 26.02.94 14:19:22  by  Kai Iske.   LogMessage :
  57. **   - Move will refuse to move a dir to itself now.
  58. **  -*-  created on Saturday, 26.02.94 14:15:24  by  Kai Iske.   LogMessage :
  59. **   - One couldn`t move a dir to another dir on the same device
  60. **
  61. ** Revision V1.8
  62. ** --------------
  63. ** created on Sunday, 19.12.93 01:44:05  by  Kai Iske.   LogMessage :
  64. **  -*-  changed on Sunday, 19.12.93 01:47:54  by  Kai Iske.   LogMessage :
  65. **   - Added PURE information to Doc, since Move really is pure
  66. **     (Suggested by : Albert-Jan Brouver)
  67. **  -*-  changed on Sunday, 19.12.93 01:46:23  by  Kai Iske.   LogMessage :
  68. **   - Due to the move-renaming bug one couldn`t rename a dir
  69. **     an Assign was put on.
  70. **     (Reported by : Albert-Jan Brouver)
  71. **  -*-  created on Sunday, 19.12.93 01:44:05  by  Kai Iske.   LogMessage :
  72. **   - Fixed move-renaming of directories.
  73. **     (Reported by : Albert-Jan Brouver)
  74. **   - Move had some severe problems recursively moving
  75. **     the contents of a directory
  76. **
  77. ** Revision V1.7
  78. ** --------------
  79. ** created on Saturday, 04.12.93 23:19:03  by  Kai Iske.   LogMessage :
  80. **  -*-  changed on Saturday, 04.12.93 23:26:25  by  Kai Iske.   LogMessage :
  81. **   - Error while moving to a "device full" disk
  82. **     (Reported by : Chris Conger)
  83. **  -*-  created on Saturday, 04.12.93 23:19:03  by  Kai Iske.   LogMessage :
  84. **   - FileName length-bug fixed
  85. **     (Reported by : Juergen Lang)
  86. **   - Recompiled using SAS 6.50
  87. **   - Stack usage reduced
  88. **
  89. ** Revision V1.6
  90. ** --------------
  91. ** created on Friday, 15.10.93 15:51:13  by  Kai Iske.   LogMessage :
  92. **  -*-  changed on Saturday, 16.10.93 15:17:29  by  Kai Iske.   LogMessage :
  93. **   - Move got screwed up, when attempting to move a
  94. **     zero size file
  95. **  -*-  changed on Friday, 15.10.93 16:03:35  by  Kai Iske.   LogMessage :
  96. **   - Added Buffer Keyword to specify the maximum buffer
  97. **     size for an inter device move. Normally Move would have used
  98. **     the max amount of available free memory in order to
  99. **     accomplish the move, or the size needed by the file...
  100. **     (Suggested by : Christof Damian)
  101. **  -*-  created on Friday, 15.10.93 15:51:13  by  Kai Iske.   LogMessage :
  102. **   - One couldn`t rename a file using move, because the
  103. **     "destination" file was removed before doing the rename,
  104. **     ie. the source file was deleted.
  105. **     (Reported by : Chris Conger)
  106. **
  107. ** Revision V1.5
  108. ** --------------
  109. ** created on Tuesday, 05.10.93 01:42:53  by  Kai Iske.   LogMessage :
  110. **  -*-  changed on Tuesday, 05.10.93 02:03:22  by  Kai Iske.   LogMessage :
  111. **   - Freed the FileInfoBlock _BEFORE_ setting the Bits, Comment
  112. **     etc. This lead to MungWall hits (of course it did)
  113. **     (Reported by Nico Francois)
  114. **  -*-  created on Tuesday, 05.10.93 01:42:53  by  Kai Iske.   LogMessage :
  115. **   - Exidentially called one ExAll() without ED_SIZE
  116. **     This lead to some calls to DoTheMove without the Size set ;)
  117. **     (Reported by  Karsten Weiss)
  118. **
  119. ** Revision V1.4
  120. ** --------------
  121. ** created on Friday, 01.10.93 16:55:15  by  Kai Iske.   LogMessage :
  122. **  -*-  created on Friday, 01.10.93 16:55:15  by  Kai Iske.   LogMessage :
  123. **   - Now uses Rename() when source and dest are on the same
  124. **     device. This is faster ;) Why haven`t I thought of that
  125. **     earlier ??? ;)
  126. **
  127. ** Revision V1.3
  128. ** --------------
  129. ** created on Wednesday, 25.08.93 16:32:43  by  Kai Iske.   LogMessage :
  130. **   - UnLock Problem solved when doing recursive Dir-Moves
  131. **     This bug lead to "Object in use" error messages
  132. **
  133. ** Revision V1.2
  134. ** --------------
  135. ** created on Tuesday, 17.08.93 22:48:38  by  Kai Iske.   LogMessage :
  136. **   - Added CTRL-C checking
  137. **   - Added FORCE Flag in order to move read/deleteprotected or
  138. **     to overwrite a delete/writeprotected files
  139. **
  140. ** Revision V1.1
  141. ** --------------
  142. ** created on Monday, 16.08.93 22:53:34  by  Kai Iske.   LogMessage :
  143. **   - Added well known CLONE, DATES, COM, NOPRO,
  144. **     QUIET and NOREQ options also used by e.g. Rename
  145. **
  146. ** Revision V1.0
  147. ** --------------
  148. ** created on Wednesday, 11.08.93 15:01:14  by  Kai Iske.   LogMessage :
  149. **     --- Initial release ---
  150. **
  151. *********************************************************************************/
  152. #define REVISION "37.11"
  153. #define REVDATE  "12.01.95"
  154. #define REVTIME  "13:26:43"
  155. #define AUTHOR   "Kai Iske"
  156. #define VERNUM   37
  157. #define REVNUM   11
  158.  
  159. #include    <string.h>
  160. #include    <stdlib.h>
  161. #include    <exec/types.h>
  162. #include    <proto/exec.h>
  163. #include    <proto/dos.h>
  164. #include    <exec/memory.h>
  165. #include    <exec/execbase.h>
  166. #include    <dos/exall.h>
  167. #include    <dos/dos.h>
  168. #include    <dos/dosextens.h>
  169.  
  170.  
  171.  
  172.  
  173.  
  174. /**********************************************************************/
  175. /*                         Defines for Flags                          */
  176. /**********************************************************************/
  177. #define    CLONE        0x0001
  178. #define    DATES        0x0002
  179. #define    NOPRO        0x0004
  180. #define    COM        0x0008
  181. #define    QUIET        0x0010
  182. #define    FORCE        0x0020
  183.  
  184. #define    WATCHSIGS    SIGBREAKF_CTRL_C
  185.  
  186.  
  187.  
  188. /**********************************************************************/
  189. /*                      Static char definitions                       */
  190. /**********************************************************************/
  191. static    const char    *Version    = "$VER: Move "REVISION" ("REVDATE")\0";
  192. 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";
  193. enum    {FROM_ARG, TO_ARG, CLONE_ARG, DATES_ARG, NOPRO_ARG, COM_ARG, QUIET_ARG, NOREQ_ARG, FORCE_ARG, BUFFER_ARG, LAST_ARG};
  194.  
  195.  
  196.  
  197. /**********************************************************************/
  198. /*                             Prototypes                             */
  199. /**********************************************************************/
  200. int        __saveds DoMove(void);
  201. static    BOOL    __stdargs DoTheMove(char *FromFile, char *ToPath, BOOL PatternFrom, BPTR OutHandle, LONG Type, ULONG Size, UWORD CopyFlags, LONG *HitMask, ULONG MaxBuffer, ULONG RecDepth);
  202. static    BOOL    __stdargs DoMoveFile(char *FromFile, char *ToPath, char *Buffer, BPTR OutHandle, ULONG Size, UWORD CopyFlags, LONG *HitMask, ULONG MaxBuffer);
  203.  
  204.  
  205.  
  206. /**********************************************************************/
  207. /*                           Library bases                            */
  208. /**********************************************************************/
  209. struct    DosLibrary    *DOSBase    = NULL;
  210.  
  211.  
  212.  
  213. /**********************************************************************/
  214. /*                          The main program                          */
  215. /**********************************************************************/
  216. int __saveds DoMove(void)
  217. {
  218.     struct    FileInfoBlock    *FIB;
  219.     struct    ExecBase    *SysBase    = *((struct ExecBase **)0x4L);
  220.     struct    Process        *MyProc        = (struct Process *)SysBase->ThisTask;
  221.     struct    RDArgs        *RDArgs;
  222.     struct    ExAllControl    *EAC;
  223.     struct    ExAllData    *EAB, *EAD;
  224.     APTR            *Args,
  225.                 *OldWindow    = NULL;
  226.     BPTR            DirLock,
  227.                 OutHandle;
  228.     char            **FromPtr;
  229.     char            *ToPtr;
  230.     char            *Pattern;
  231.     char            *PathName    = NULL;
  232.     char            *Buffer        = NULL;
  233.     LONG            HitMask        = 0;
  234.     UWORD            NumFrom        = 0,
  235.                 PatternType,
  236.                 CopyFlags    = 0;
  237.     ULONG            MaxBuffer    = 0;
  238.     BOOL            PatternFrom,
  239.                 GoOn        = FALSE,
  240.                 Scanning;
  241.  
  242.  
  243.  
  244.  
  245.         // Ignore startup from WB
  246.  
  247.     if(!(MyProc->pr_CLI))
  248.     {
  249.         struct    Message    *MyMsg;
  250.  
  251.         WaitPort(&MyProc->pr_MsgPort);
  252.         MyMsg = GetMsg(&MyProc->pr_MsgPort);
  253.         Disable();
  254.         ReplyMsg(MyMsg);
  255.         return(10);
  256.     }
  257.  
  258.         // Do the wild thing
  259.  
  260.     if((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)))
  261.     {
  262.             // Allocate buffers
  263.  
  264.         if((Pattern = AllocVec(1024, MEMF_CLEAR)) && (PathName = AllocVec(1024, MEMF_CLEAR)) && (Buffer = AllocVec(1024, MEMF_CLEAR)))
  265.         {
  266.             if((FIB = AllocVec(sizeof(struct FileInfoBlock), MEMF_CLEAR)))
  267.             {
  268.                     // Get buffer for ReadArgs()
  269.  
  270.                 if((Args = AllocVec((LAST_ARG * sizeof(ULONG)), MEMF_CLEAR)))
  271.                 {
  272.                         // Get structure for ExAll()
  273.  
  274.                     if((EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  275.                     {
  276.                             // Get buffer for ExAll()
  277.  
  278.                         if((EAB = AllocVec((sizeof(struct ExAllData)*20), MEMF_CLEAR)))
  279.                         {
  280.                                 // Parse commandline
  281.  
  282.                             if((RDArgs = ReadArgs((char *)Template, (LONG *)Args, NULL)))
  283.                             {
  284.                                     // From and to really there ??
  285.  
  286.                                 if(Args[FROM_ARG] && Args[TO_ARG])
  287.                                 {
  288.                                         // A O.K. so far
  289.  
  290.                                     GoOn        = TRUE;
  291.  
  292.                                         // Get output handle
  293.  
  294.                                     OutHandle    = Output();
  295.  
  296.                                         // Get Flags
  297.  
  298.                                     if(Args[CLONE_ARG])
  299.                                         CopyFlags    |=    CLONE;
  300.                                     if(Args[DATES_ARG])
  301.                                         CopyFlags    |=    DATES;
  302.                                     if(Args[NOPRO_ARG])
  303.                                         CopyFlags    |=    NOPRO;
  304.                                     if(Args[COM_ARG])
  305.                                         CopyFlags    |=    COM;
  306.                                     if(Args[QUIET_ARG])
  307.                                         CopyFlags    |=    QUIET;
  308.                                     if(Args[FORCE_ARG])
  309.                                         CopyFlags    |=    FORCE;
  310.                                     if(Args[BUFFER_ARG])
  311.                                         MaxBuffer    =    *((ULONG *)Args[BUFFER_ARG]) * 1024;
  312.  
  313.                                         // Check for NOREQ Option
  314.  
  315.                                     if(Args[NOREQ_ARG])
  316.                                     {
  317.                                         OldWindow        = MyProc->pr_WindowPtr;
  318.                                         MyProc->pr_WindowPtr    = (void *)(-1L);
  319.                                     }
  320.  
  321.                                         // Get pointers to Files
  322.  
  323.                                     FromPtr    = (char **)Args[FROM_ARG];
  324.                                     ToPtr    = (char *)Args[TO_ARG];
  325.  
  326.                                         // Count FROM entries
  327.  
  328.                                     while(*FromPtr++)
  329.                                         NumFrom++;
  330.  
  331.                                         // Restore FromPtr
  332.  
  333.                                     FromPtr    = (char **)Args[FROM_ARG];
  334.  
  335.                                         // Set pattern if there are more than 1
  336.                                         // FROM files or if the only FROM file
  337.                                         // is a pattern
  338.  
  339.                                     if(NumFrom > 1)
  340.                                         PatternFrom = TRUE;
  341.                                     else
  342.                                         PatternFrom = ParsePatternNoCase(*FromPtr, Pattern, 1024);
  343.  
  344.                                         // If a pattern is used, check
  345.                                         // whether the dest really is a dir
  346.  
  347.                                     if(PatternFrom)
  348.                                     {
  349.                                             // Try to obtain a lock
  350.  
  351.                                         if((DirLock = Lock(ToPtr, ACCESS_READ)))
  352.                                         {
  353.                                                 // Check file
  354.  
  355.                                             if(Examine(DirLock, FIB))
  356.                                             {
  357.                                                     // Get type of destination entry
  358.  
  359.                                                 GoOn = (FIB->fib_DirEntryType >= 0);
  360.  
  361.                                                     // If it`s not a directory (multiple files are to be moved)
  362.                                                     // issue an error
  363.  
  364.                                                 if(!GoOn)
  365.                                                     FPuts(OutHandle, "\nMove : Multiple files may not be moved to a single file\n");
  366.                                             }
  367.                                             else
  368.                                             {
  369.                                                     // Examine() failed -> Abort
  370.  
  371.                                                 GoOn = FALSE;
  372.                                                 PrintFault(IoErr(), "\nMove ");
  373.                                             }
  374.  
  375.                                                 // Unlock CheckDir
  376.  
  377.                                             UnLock(DirLock);
  378.                                         }
  379.                                         else
  380.                                         {
  381.                                                 // If lock failed issue an error
  382.  
  383.                                             PrintFault(IoErr(), "\nMove ");
  384.                                             GoOn = FALSE;
  385.                                         }
  386.                                     }
  387.  
  388.  
  389.  
  390.                                         // Loop for all source files
  391.  
  392.                                     while(NumFrom && GoOn)
  393.                                     {
  394.                                             // Check for CTRL-C
  395.  
  396.                                         if(GoOn)
  397.                                             HitMask    = CheckSignal(WATCHSIGS);
  398.  
  399.                                         if(!HitMask && GoOn)
  400.                                         {
  401.                                                 // Check if this source is a pattern
  402.  
  403.                                             strcpy(Buffer, FilePart(*FromPtr));
  404.                                             strupr(Buffer);
  405.                                             PatternType = ParsePatternNoCase(Buffer, Pattern, 1024);
  406.  
  407.                                                 // It is a pattern
  408.  
  409.                                             if(PatternType == 1)
  410.                                             {
  411.                                                     // Create name of source
  412.  
  413.                                                 strcpy(Buffer, *FromPtr);
  414.                                                 *PathPart(Buffer)    = '\0';
  415.  
  416.                                                     // Get Lock for Source - Directory
  417.  
  418.                                                 if((DirLock = Lock(Buffer, ACCESS_READ)))
  419.                                                 {
  420.                                                         // Setup ExAllControl-Structure
  421.  
  422.                                                     EAC->eac_LastKey    = 0L;
  423.                                                     EAC->eac_MatchString    = Pattern;
  424.                                                     EAC->eac_MatchFunc    = NULL;
  425.  
  426.                                                     do
  427.                                                     {
  428.                                                             // Check for CTRL-C
  429.  
  430.                                                         if(GoOn)
  431.                                                             HitMask = CheckSignal(WATCHSIGS);
  432.  
  433.                                                         if(HitMask)
  434.                                                             GoOn = FALSE;
  435.  
  436.                                                             // Scan directory
  437.  
  438.                                                         Scanning = ExAll(DirLock, EAB, (20*sizeof(struct ExAllData)), ED_SIZE, EAC);
  439.  
  440.                                                             // Issue Error
  441.  
  442.                                                         if(GoOn && (!Scanning) && (IoErr() != ERROR_NO_MORE_ENTRIES))
  443.                                                         {
  444.                                                             PrintFault(IoErr(), "\nMove ");
  445.                                                             GoOn = FALSE;
  446.                                                         }
  447.  
  448.                                                             // End of Dir reached
  449.  
  450.                                                         if(EAC->eac_Entries == 0)
  451.                                                             Scanning = FALSE;
  452.                                                         else if(GoOn)
  453.                                                         {
  454.                                                             EAD    = EAB;
  455.  
  456.                                                             do
  457.                                                             {
  458.                                                                     // Check for CTRL-C
  459.  
  460.                                                                 if(GoOn)
  461.                                                                     HitMask = CheckSignal(WATCHSIGS);
  462.  
  463.                                                                 if(!HitMask && GoOn)
  464.                                                                 {
  465.                                                                         // Create filename for this file to be moved
  466.  
  467.                                                                     strcpy(PathName, *FromPtr);
  468.                                                                     *PathPart(PathName)    = '\0';
  469.                                                                     AddPart(PathName, EAD->ed_Name, 1024);
  470.  
  471.                                                                         // Move file
  472.  
  473.                                                                     GoOn    = DoTheMove(PathName, ToPtr, TRUE, OutHandle, EAD->ed_Type, EAD->ed_Size, CopyFlags, &HitMask, MaxBuffer, 1);
  474.  
  475.                                                                     EAD    = EAD->ed_Next;
  476.                                                                 }
  477.                                                                 else
  478.                                                                     GoOn = FALSE;
  479.  
  480.                                                             } while(EAD && GoOn);
  481.                                                         }
  482.                                                     } while(Scanning);
  483.  
  484.                                                         // Unlock source directory
  485.  
  486.                                                     UnLock(DirLock);
  487.                                                 }
  488.                                                 else
  489.                                                 {
  490.                                                         // Issue error, if dir could not be locked
  491.  
  492.                                                     PrintFault(IoErr(), "\nMove ");
  493.                                                     GoOn    = FALSE;
  494.                                                 }
  495.                                             }
  496.                                                 // No pattern
  497.  
  498.                                             else if(PatternType == 0)
  499.                                             {
  500.                                                     // Try to lock source file/dir
  501.  
  502.                                                 if((DirLock = Lock(*FromPtr, ACCESS_READ)))
  503.                                                 {
  504.                                                         // Examine this lock
  505.  
  506.                                                     if(Examine(DirLock, FIB))
  507.                                                     {
  508.                                                             // Unlock directory and do the move
  509.  
  510.                                                         UnLock(DirLock);
  511.                                                         GoOn    = DoTheMove(*FromPtr, ToPtr, TRUE, OutHandle, FIB->fib_DirEntryType, FIB->fib_Size, CopyFlags, &HitMask, MaxBuffer, 1);
  512.                                                     }
  513.                                                     else
  514.                                                     {
  515.                                                             // Issue error on failed Examine()
  516.  
  517.                                                         PrintFault(IoErr(), "\nMove ");
  518.                                                         GoOn = FALSE;
  519.                                                         UnLock(DirLock);
  520.                                                     }
  521.                                                 }
  522.                                                 else
  523.                                                 {
  524.                                                         // No Lock() no more moves
  525.  
  526.                                                     PrintFault(IoErr(), "\nMove ");
  527.                                                     GoOn = FALSE;
  528.                                                 }
  529.                                             }
  530.  
  531.                                                 // Error condition
  532.  
  533.                                             else
  534.                                             {
  535.                                                 PrintFault(IoErr(), "\nMove ");
  536.                                                 GoOn = FALSE;
  537.                                             }
  538.  
  539.                                             NumFrom--;
  540.                                             FromPtr++;
  541.                                         }
  542.                                         else
  543.                                             GoOn    = FALSE;
  544.                                     }
  545.                                 }
  546.  
  547.                                     // Free ReadArgs
  548.  
  549.                                 FreeArgs(RDArgs);
  550.                             }
  551.                             else
  552.                                 PrintFault(IoErr(), "\nMove ");
  553.  
  554.                                 // Free ExAll-Buffer
  555.  
  556.                             FreeVec(EAB);
  557.                         }
  558.                         else
  559.                             PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  560.  
  561.                             // Free ExAllControl Structure
  562.  
  563.                         FreeDosObject(DOS_EXALLCONTROL, (void *)EAC);
  564.                     }
  565.                     else
  566.                         PrintFault(IoErr(), "\nMove ");
  567.  
  568.                         // Free Argument Buffer
  569.  
  570.                     FreeVec(Args);
  571.                 }
  572.                 else
  573.                     PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  574.  
  575.                 FreeVec(FIB);
  576.             }
  577.             else
  578.                 PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  579.         }
  580.         else
  581.             PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  582.  
  583.  
  584.             // Free allocated buffers
  585.  
  586.         if(Pattern)
  587.             FreeVec(Pattern);
  588.  
  589.         if(PathName)
  590.             FreeVec(PathName);
  591.  
  592.         if(Buffer)
  593.             FreeVec(Buffer);
  594.  
  595.  
  596.             // Check for Abort-Signals
  597.  
  598.         if(HitMask && !(CopyFlags & QUIET))
  599.         {
  600.                 // Display appropriate message
  601.  
  602.             if(HitMask & SIGBREAKF_CTRL_C)
  603.                 FPuts(OutHandle, "\nMove ^C...\n");
  604.         }
  605.  
  606.             // Close DOSLibrary
  607.  
  608.         CloseLibrary((struct Library *)DOSBase);
  609.     }
  610.  
  611.         // Restore old window pointer (if any)
  612.  
  613.     if(OldWindow)
  614.         MyProc->pr_WindowPtr    = OldWindow;
  615.  
  616.  
  617.         // Depending on this flag return appropriate return code
  618.  
  619.     if(GoOn)
  620.         return(0);
  621.     else
  622.         return(10);
  623. }
  624.  
  625.  
  626.  
  627.  
  628. /**********************************************************************/
  629. /*                            Do the move                             */
  630. /**********************************************************************/
  631. static BOOL __stdargs DoTheMove(char *FromFile, char *ToPath, BOOL PatternFrom, BPTR OutHandle, LONG Type, ULONG Size, UWORD CopyFlags, LONG *HitMask, ULONG MaxBuffer, ULONG RecDepth)
  632. {
  633.     struct    ExAllControl    *EAC;
  634.     struct    ExAllData    *EAB, *EAD;
  635.     char    *NewDir;
  636.     char    *Buffer        = NULL;
  637.     char    *ToDir        = NULL;
  638.     char    *DispBuff    = NULL;
  639.     UWORD    Len;
  640.     BPTR    DirLock;
  641.     BOOL    RetVal        = TRUE,
  642.         Scanning,
  643.         DoRename    = FALSE,
  644.         MoveDirToSame    = FALSE,
  645.         Skipped        = FALSE;
  646.  
  647.  
  648.         // Try to allocate buffers
  649.  
  650.     if((NewDir = AllocVec(1024, MEMF_CLEAR)) && (Buffer = AllocVec(1024, MEMF_CLEAR)) && (ToDir = AllocVec(1024, MEMF_CLEAR)) && (DispBuff = AllocVec(1024, MEMF_CLEAR)))
  651.     {
  652.             // Is it a directory ???
  653.             // If yes, recursively loop for all entries within dir
  654.  
  655.         if(Type >= 0)
  656.         {
  657.             strcpy(Buffer, FromFile);
  658.  
  659.                 // Get length of from name
  660.  
  661.             Len    = strlen(Buffer);
  662.  
  663.                 // Really got a from name ?!?
  664.  
  665.             if(Len)
  666.             {
  667.                 if(Buffer[Len - 1] == '/')
  668.                     Buffer[Len - 1] = '\0';
  669.  
  670.                     // Copy dest name to buffer
  671.  
  672.                 strcpy(NewDir, ToPath);
  673.  
  674.                     // Check for dir moving to itself...
  675.                     // ...and for renaming
  676.  
  677.                 if((DirLock = Lock(Buffer, ACCESS_READ)))
  678.                 {
  679.                     BPTR    TestLock;
  680.  
  681.                     if((TestLock = Lock(NewDir, ACCESS_READ)))
  682.                     {
  683.                             // Working on same volume?
  684.  
  685.                         DoRename    = (SameLock(DirLock, TestLock) == LOCK_SAME_VOLUME);
  686.  
  687.                             // Renaming a directory ???
  688.  
  689.                         MoveDirToSame    = (SameLock(DirLock, TestLock) == LOCK_SAME);
  690.  
  691.                         UnLock(TestLock);
  692.                     }
  693.  
  694.                     UnLock(DirLock);
  695.                 }
  696.  
  697.  
  698.                     // Ok, we are to move
  699.                     // If a pattern is used print the name of the dir to be moved
  700.  
  701.                 if(PatternFrom && !(CopyFlags & QUIET))
  702.                 {
  703.                     int    i;
  704.  
  705.                         // Prepend number of spaces according to recursion depth
  706.  
  707.                     for(i = 0; i < RecDepth; i++)
  708.                         DispBuff[i]    = ' ';
  709.                     DispBuff[i]    = '\0';
  710.  
  711.                     strcat(DispBuff, FromFile);
  712.                     strcat(DispBuff, "...");
  713.                     Write(OutHandle, " ", 1);
  714.                     Write(OutHandle, DispBuff, strlen(DispBuff));
  715.                 }
  716.  
  717.  
  718.                     // Destination directory available ???
  719.                     // If so, we are to move to that directory
  720.                     // Otherwise, we`ll simply rename
  721.  
  722.                 if((DirLock = Lock(NewDir, ACCESS_READ)))
  723.                 {
  724.                     UnLock(DirLock);
  725.  
  726.                         // Add name of from directory
  727.  
  728.                     if(!MoveDirToSame)
  729.                         AddPart(NewDir, FilePart(Buffer), 1024);
  730.                 }
  731.  
  732.  
  733.                     // Simple rename; no cross-device move ?!?
  734.  
  735.                 if(DoRename)
  736.                 {
  737.                     BOOL    DoTheRename    = TRUE;
  738.  
  739.                         // Trying to rename a directory?
  740.                         // Only allowed when not in pattern or multimode
  741.  
  742.                     if(MoveDirToSame)
  743.                         DoTheRename    = !PatternFrom;
  744.  
  745.                         // Still rename the directory?
  746.  
  747.                     if(DoTheRename)
  748.                     {
  749.                         BPTR    TestLock;
  750.  
  751.                             // Destination is already there?
  752.                             // If so, only move contents
  753.  
  754.                         if((TestLock = Lock(NewDir, ACCESS_READ)))
  755.                         {
  756.                             DoRename    = FALSE;
  757.                             UnLock(TestLock);
  758.                         }
  759.                         else
  760.                         {
  761.                                 // Do the rename
  762.  
  763.                             if(!Rename(Buffer, NewDir))
  764.                             {
  765.                                 PrintFault(IoErr(), "\nMove ");
  766.                                 RetVal = FALSE;
  767.                             }
  768.                         }
  769.                     }
  770.                     else
  771.                         Skipped    = TRUE;
  772.                 }
  773.  
  774.                 if(!DoRename)
  775.                 {
  776.                         // Clone directory name of source
  777.  
  778.                     strcpy(ToDir, Buffer);
  779.  
  780.                         // Try to lock directory or
  781.                         // create it, if not existent
  782.  
  783.                     if(!(DirLock = Lock(NewDir, ACCESS_READ)))
  784.                     {
  785.                         if((DirLock = CreateDir(NewDir)) && PatternFrom && !(CopyFlags & QUIET))
  786.                             Write(OutHandle, " [created]...", 13);
  787.                     }
  788.  
  789.                         // Got the destination directory ???
  790.  
  791.                     if(DirLock)
  792.                     {
  793.                             // Unlock Directory
  794.  
  795.                         UnLock(DirLock);
  796.  
  797.                             // Lock sourcedirectory
  798.  
  799.                         if((DirLock = Lock(Buffer, ACCESS_READ)))
  800.                         {
  801.                                 // Get ExAll Control for recursive directory search
  802.  
  803.                             if((EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  804.                             {
  805.                                     // Allocate buffer for move
  806.  
  807.                                 if((EAB = AllocVec((20*sizeof(struct ExAllData)), MEMF_CLEAR)))
  808.                                 {
  809.                                     EAC->eac_LastKey    = 0L;
  810.                                     EAC->eac_MatchString    = NULL;
  811.                                     EAC->eac_MatchFunc    = NULL;
  812.  
  813.                                     do
  814.                                     {
  815.                                             // Check for CTRL-C
  816.  
  817.                                         if(RetVal)
  818.                                             (*HitMask) = CheckSignal(WATCHSIGS);
  819.  
  820.                                         if((*HitMask))
  821.                                             RetVal = FALSE;
  822.  
  823.                                             // Scan directory for entries
  824.  
  825.                                         Scanning = ExAll(DirLock, EAB, (20*sizeof(struct ExAllData)), ED_SIZE, EAC);
  826.  
  827.                                             // Check for an error
  828.  
  829.                                         if(RetVal && (!Scanning) && (IoErr() != ERROR_NO_MORE_ENTRIES))
  830.                                         {
  831.                                             PrintFault(IoErr(), "\nMove ");
  832.                                             RetVal = FALSE;
  833.                                         }
  834.  
  835.                                             // End of Dir reached
  836.  
  837.                                         if(EAC->eac_Entries == 0)
  838.                                             Scanning = FALSE;
  839.                                         else if(RetVal)
  840.                                         {
  841.                                             EAD = EAB;
  842.  
  843.                                             do
  844.                                             {
  845.                                                     // Check for CTRL-C
  846.  
  847.                                                 if(RetVal)
  848.                                                     (*HitMask) = CheckSignal(WATCHSIGS);
  849.  
  850.                                                 if(!(*HitMask) && RetVal)
  851.                                                 {
  852.                                                         // Create filename of source
  853.  
  854.                                                     strcpy(Buffer, FromFile);
  855.                                                     AddPart(Buffer, EAD->ed_Name, 1024);
  856.  
  857.                                                         // And start recursion
  858.  
  859.                                                     RetVal = DoTheMove(Buffer, NewDir, FALSE, OutHandle, EAD->ed_Type, EAD->ed_Size, CopyFlags, HitMask, MaxBuffer, RecDepth + 1);
  860.  
  861.                                                         // Loop for all entries
  862.  
  863.                                                     EAD = EAD->ed_Next;
  864.                                                 }
  865.                                                 else
  866.                                                     RetVal = FALSE;
  867.  
  868.                                             } while(EAD && RetVal);
  869.                                         }
  870.                                     } while(Scanning);
  871.  
  872.                                         // Free ExAll Buffer
  873.  
  874.                                     FreeVec(EAB);
  875.                                 }
  876.                                 else
  877.                                 {
  878.                                     PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  879.                                     RetVal = FALSE;
  880.                                 }
  881.  
  882.                                     // Free ExAllControl Structure
  883.  
  884.                                 FreeDosObject(DOS_EXALLCONTROL, EAC);
  885.                             }
  886.                             else
  887.                             {
  888.                                 PrintFault(IoErr(), "\nMove ");
  889.                                 RetVal = FALSE;
  890.                             }
  891.  
  892.                             UnLock(DirLock);
  893.                         }
  894.                         else
  895.                         {
  896.                             PrintFault(IoErr(), "\nMove ");
  897.                             RetVal = FALSE;
  898.                         }
  899.                     }
  900.                     else
  901.                     {
  902.                         PrintFault(IoErr(), "\nMove ");
  903.                         RetVal = FALSE;
  904.                     }
  905.                 }
  906.  
  907.                     // Ok, this dir was moved (no rename), so remove it
  908.  
  909.                 if(RetVal && !DoRename)
  910.                 {
  911.                         // With force mode set on,
  912.                         // First make dir deletable
  913.  
  914.                     if(CopyFlags & FORCE)
  915.                         SetProtection(ToDir, ~(FIBF_OTR_WRITE|FIBF_OTR_DELETE|FIBF_WRITE|FIBF_DELETE));
  916.  
  917.                         // Delete directory
  918.  
  919.                     if(!DeleteFile(ToDir))
  920.                     {
  921.                         PrintFault(IoErr(), "\nMove ");
  922.                         RetVal = FALSE;
  923.                     }
  924.                 }
  925.  
  926.                     // Display "moved" message
  927.  
  928.                 if(PatternFrom && RetVal && !(CopyFlags & QUIET))
  929.                 {
  930.                     if(!Skipped)
  931.                         FPuts(OutHandle, " moved\n");
  932.                     else
  933.                         FPuts(OutHandle, " skipped\n");
  934.                 }
  935.             }
  936.         }
  937.         else
  938.         {
  939.                 // Ok, we are to move
  940.                 // If a pattern is used print the name of the file to be moved
  941.  
  942.             if(PatternFrom && !(CopyFlags & QUIET))
  943.             {
  944.                 int    i;
  945.  
  946.                     // Prepend number of spaces according to recursion depth
  947.  
  948.                 for(i = 0; i < RecDepth; i++)
  949.                     DispBuff[i]    = ' ';
  950.                 DispBuff[i]    = '\0';
  951.  
  952.                 strcat(DispBuff, FromFile);
  953.                 strcat(DispBuff, "...");
  954.                 Write(OutHandle, " ", 1);
  955.                 Write(OutHandle, DispBuff, strlen(DispBuff));
  956.             }
  957.  
  958.                 // On a plain file -> Simply move it
  959.  
  960.             RetVal = DoMoveFile(FromFile, ToPath, Buffer, OutHandle, Size, CopyFlags, HitMask, MaxBuffer);
  961.  
  962.                 // If there was a pattern (or a single directory)
  963.                 // end the Move string
  964.  
  965.             if(PatternFrom && RetVal && !(CopyFlags & QUIET))
  966.             {
  967.                 if(!Skipped)
  968.                     FPuts(OutHandle, " moved\n");
  969.                 else
  970.                     FPuts(OutHandle, " skipped\n");
  971.             }
  972.         }
  973.     }
  974.     else
  975.     {
  976.         PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  977.         RetVal = FALSE;
  978.     }
  979.  
  980.         // De-Allocate buffers
  981.  
  982.     if(NewDir)
  983.         FreeVec(NewDir);
  984.  
  985.     if(Buffer)
  986.         FreeVec(Buffer);
  987.  
  988.     if(ToDir)
  989.         FreeVec(ToDir);
  990.  
  991.     if(DispBuff)
  992.         FreeVec(DispBuff);
  993.  
  994.         // Return Code
  995.  
  996.     return(RetVal);
  997. }
  998.  
  999.  
  1000.  
  1001.  
  1002.  
  1003.  
  1004.  
  1005.  
  1006. /**********************************************************************/
  1007. /*                       Physically move a file                       */
  1008. /**********************************************************************/
  1009. static BOOL __stdargs DoMoveFile(char *FromFile, char *ToPath, char *Buffer, BPTR OutHandle, ULONG Size, UWORD CopyFlags, LONG *HitMask, ULONG MaxBuffer)
  1010. {
  1011.     struct    FileInfoBlock    *FIB;
  1012.     BPTR            InFile,
  1013.                 OutFile;
  1014.     char            *DestName;
  1015.     APTR            CopyBuffer;
  1016.     ULONG            ReadSize,
  1017.                 AvailSize;
  1018.     LONG            InKey        = -1,
  1019.                 OutKey        = -1;
  1020.     BOOL            RetVal        = TRUE,
  1021.                 ErrCpy        = FALSE,
  1022.                 LoopCpy        = TRUE,
  1023.                 DoRename    = FALSE,
  1024.                 RemoveFirst    = FALSE;
  1025.  
  1026.  
  1027.         // Allocate buffer for Destination name
  1028.  
  1029.     if(!(DestName = AllocVec(1024, MEMF_CLEAR)))
  1030.     {
  1031.         PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  1032.         return(FALSE);
  1033.     }
  1034.  
  1035.     if((FIB = AllocVec(sizeof(struct FileInfoBlock), MEMF_CLEAR)))
  1036.     {
  1037.  
  1038.         strcpy(DestName, ToPath);
  1039.  
  1040.             // Check, if destfile already exists
  1041.             // If so, check if it`s a dir.
  1042.             // Yes -> Copy with sourcename
  1043.             // No -> Copy with given name
  1044.  
  1045.         if((OutFile = Lock(DestName, ACCESS_READ)))
  1046.         {
  1047.             if(Examine(OutFile, FIB))
  1048.             {
  1049.                     // If dest is a directory move with source name
  1050.  
  1051.                 if(FIB->fib_DirEntryType >= 0)
  1052.                     AddPart(DestName, FilePart(FromFile), 1024);
  1053.                 else
  1054.                 {
  1055.                     OutKey        = ((struct FileLock *)BADDR(OutFile))->fl_Key;
  1056.                     RemoveFirst    = TRUE;
  1057.                 }
  1058.             }
  1059.             else
  1060.             {
  1061.                     // No examine -> Use source filename
  1062.  
  1063.                 AddPart(DestName, FilePart(FromFile), 1024);
  1064.             }
  1065.  
  1066.             UnLock(OutFile);
  1067.         }
  1068.  
  1069.             // Try to lock input file
  1070.  
  1071.         if((InFile = Lock(FromFile, ACCESS_READ)))
  1072.         {
  1073.                 // Get DiskBlock for inputfile
  1074.  
  1075.             InKey    = ((struct FileLock *)BADDR(InFile))->fl_Key;
  1076.  
  1077.                 // Get old protection bits, comment and filedate
  1078.  
  1079.             if(Examine(InFile, FIB))
  1080.             {
  1081.                     // In Force mode -> Force read and delete permissons
  1082.                     // for input file
  1083.  
  1084.                 if(CopyFlags & FORCE)
  1085.                     SetProtection(FromFile, ~(FIBF_OTR_READ|FIBF_OTR_DELETE|FIBF_READ|FIBF_DELETE));
  1086.             }
  1087.             else
  1088.             {
  1089.                 PrintFault(IoErr(), "\nMove ");
  1090.                 RetVal = FALSE;
  1091.             }
  1092.  
  1093.                 // If so, unlock
  1094.  
  1095.             UnLock(InFile);
  1096.         }
  1097.         else
  1098.         {
  1099.             PrintFault(IoErr(), "\nMove ");
  1100.             RetVal = FALSE;
  1101.         }
  1102.  
  1103.             // Can we possibly simple rename the file?
  1104.  
  1105.         if((InFile = Lock(FromFile, ACCESS_READ)))
  1106.         {
  1107.             if((OutFile = Lock(ToPath, ACCESS_READ)))
  1108.             {
  1109.                 DoRename    = (SameLock(InFile, OutFile) == LOCK_SAME_VOLUME);
  1110.  
  1111.                 UnLock(OutFile);
  1112.             }
  1113.  
  1114.             UnLock(InFile);
  1115.         }
  1116.  
  1117.             // No Rename -> Do the right move ;)
  1118.  
  1119.         if(!DoRename)
  1120.         {
  1121.                 // Open Input file
  1122.  
  1123.             if(RetVal && (InFile = Open(FromFile, MODE_OLDFILE)))
  1124.             {
  1125.                     // Outfile already there ??? and in force mode ???
  1126.  
  1127.                 if((CopyFlags & FORCE) && ((OutFile = Lock(DestName, ACCESS_READ))))
  1128.                 {
  1129.                         // Force delete and write permissons
  1130.  
  1131.                     UnLock(OutFile);
  1132.                     SetProtection(DestName, ~(FIBF_OTR_WRITE|FIBF_OTR_DELETE|FIBF_WRITE|FIBF_DELETE));
  1133.                 }
  1134.  
  1135.  
  1136.                     // Open Output file
  1137.  
  1138.                 if((OutFile = Open(DestName, MODE_NEWFILE)))
  1139.                 {
  1140.                         // Is there any data within the file ???
  1141.  
  1142.                     if(Size)
  1143.                     {
  1144.                             // Get available size of memory
  1145.                             // or take the user`s buffer size into account
  1146.  
  1147.                         AvailSize    = (MaxBuffer != 0) ? MaxBuffer : (AvailMem(MEMF_LARGEST) - 102400);
  1148.                         Size        = (Size > AvailSize) ? AvailSize : Size;
  1149.  
  1150.                             // Loop till we get a buffer
  1151.  
  1152.                         while(Size && !(CopyBuffer = AllocVec(Size, MEMF_CLEAR)))
  1153.                             Size    -= 1024;
  1154.  
  1155.  
  1156.                         if(CopyBuffer)
  1157.                         {
  1158.                                 // Loop for portions of the source file
  1159.  
  1160.                             while(RetVal && LoopCpy)
  1161.                             {
  1162.                                     // Check for CTRL-C
  1163.  
  1164.                                 if(RetVal)
  1165.                                     (*HitMask) = CheckSignal(WATCHSIGS);
  1166.  
  1167.                                 if(!(*HitMask) && RetVal)
  1168.                                 {
  1169.                                         // Read part of file
  1170.  
  1171.                                     if((ReadSize = Read(InFile, CopyBuffer, Size)) > 0)
  1172.                                     {
  1173.                                             // And write it back
  1174.  
  1175.                                         if(Write(OutFile, CopyBuffer, ReadSize) == -1)
  1176.                                         {
  1177.                                             PrintFault(IoErr(), "\nMove ");
  1178.                                             RetVal    = FALSE;
  1179.                                             ErrCpy    = TRUE;
  1180.                                         }
  1181.                                     }
  1182.                                     else
  1183.                                     {
  1184.                                             // EOF ??? -> End copy
  1185.  
  1186.                                         if(ReadSize == 0)
  1187.                                             LoopCpy    = FALSE;
  1188.                                         else
  1189.                                         {
  1190.                                                 // Otherwise issue error
  1191.  
  1192.                                             PrintFault(IoErr(), "\nMove ");
  1193.                                             RetVal    = FALSE;
  1194.                                             ErrCpy    = TRUE;
  1195.                                         }
  1196.                                     }
  1197.                                 }
  1198.                                 else
  1199.                                     RetVal = FALSE;
  1200.                             }
  1201.  
  1202.                             FreeVec(CopyBuffer);
  1203.                         }
  1204.                         else
  1205.                         {
  1206.                             PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  1207.                             RetVal    = FALSE;
  1208.                             ErrCpy    = TRUE;
  1209.                         }
  1210.                     }
  1211.  
  1212.                     Close(OutFile);
  1213.                 }
  1214.                 else
  1215.                 {
  1216.                         // Issue error
  1217.  
  1218.                     PrintFault(IoErr(), "\nMove ");
  1219.                     RetVal = FALSE;
  1220.                 }
  1221.                     // Close InFile
  1222.  
  1223.                 Close(InFile);
  1224.             }
  1225.             else
  1226.             {
  1227.                     // Issue error
  1228.  
  1229.                 PrintFault(IoErr(), "\nMove ");
  1230.                 RetVal = FALSE;
  1231.             }
  1232.         }
  1233.         else
  1234.         {
  1235.                 // If RemoveFirst is not set, check again ;)
  1236.  
  1237.             if(!RemoveFirst)
  1238.             {
  1239.                 if((OutFile = Lock(DestName, ACCESS_READ)))
  1240.                 {
  1241.                     if(Examine(OutFile, FIB))
  1242.                     {
  1243.                             // If dest is a file, delete first
  1244.  
  1245.                         if(FIB->fib_DirEntryType < 0)
  1246.                         {
  1247.                                 // Get Disk block of dest file
  1248.  
  1249.                             OutKey    = ((struct FileLock *)BADDR(OutFile))->fl_Key;
  1250.                             RemoveFirst = TRUE;
  1251.                         }
  1252.                     }
  1253.                     UnLock(OutFile);
  1254.                 }
  1255.             }
  1256.  
  1257.                 // Check if only a rename should be accomplished
  1258.  
  1259.             if(InKey != -1 && OutKey != -1)
  1260.             {
  1261.                 if(InKey == OutKey)
  1262.                     RemoveFirst = FALSE;
  1263.             }
  1264.  
  1265.                 // In Rename() mode, the destination has to be removed first
  1266.  
  1267.             if(RemoveFirst)
  1268.             {
  1269.                     // If dest file is protected check for FORCE flag
  1270.  
  1271.                 if(CopyFlags & FORCE)
  1272.                     SetProtection(DestName, ~(FIBF_OTR_WRITE|FIBF_OTR_DELETE|FIBF_WRITE|FIBF_DELETE));
  1273.  
  1274.                 if(!DeleteFile(DestName))
  1275.                 {
  1276.                     PrintFault(IoErr(), "\nMove ");
  1277.                     RetVal = FALSE;
  1278.                 }
  1279.             }
  1280.  
  1281.             if(RetVal)
  1282.             {
  1283.                     // Now try to "rename" the file
  1284.  
  1285.                 if(!Rename(FromFile, DestName))
  1286.                 {
  1287.                     PrintFault(IoErr(), "\nMove ");
  1288.                     RetVal = FALSE;
  1289.                 }
  1290.             }
  1291.         }
  1292.  
  1293.             // Error while copying ?? -> Remove Dest file
  1294.  
  1295.         if(ErrCpy)
  1296.         {
  1297.             FPuts(OutHandle, "\nMove : Error while moving; destination removed.\n");
  1298.             DeleteFile(DestName);
  1299.         }
  1300.  
  1301.             // No Error -> Remove Source file
  1302.  
  1303.         if(RetVal && !ErrCpy)
  1304.         {
  1305.             if(!DoRename && !(RetVal = DeleteFile(FromFile)))
  1306.                 PrintFault(IoErr(), "\nMove ");
  1307.             else
  1308.             {
  1309.                     // Set bits etc. as requested
  1310.  
  1311.                 if((CopyFlags & CLONE) || (CopyFlags & DATES))
  1312.                     SetFileDate(DestName, &FIB->fib_Date);
  1313.  
  1314.                 if((CopyFlags & CLONE) || (CopyFlags & COM))
  1315.                     SetComment(DestName, FIB->fib_Comment);
  1316.  
  1317.                 if(((CopyFlags & CLONE) && !(CopyFlags & NOPRO)) || (!(CopyFlags & CLONE) && !(CopyFlags & NOPRO)))
  1318.                     SetProtection(DestName, FIB->fib_Protection);
  1319.             }
  1320.         }
  1321.  
  1322.             // Free FileInfo Block
  1323.  
  1324.         FreeVec(FIB);
  1325.     }
  1326.     else
  1327.     {
  1328.         PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  1329.         RetVal = FALSE;
  1330.     }
  1331.  
  1332.         // Free buffer for destination name
  1333.  
  1334.     FreeVec(DestName);
  1335.  
  1336.     return(RetVal);
  1337. }
  1338.