home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 1 / FFMCD01.bin / bbs / cliutil / move.lha / Move / Move.c next >
Encoding:
C/C++ Source or Header  |  1993-08-25  |  20.3 KB  |  905 lines

  1. /*
  2. Auto:        smake Move
  3. */
  4.  
  5. /* $Revision Header built automatically *************** (do not edit) ************
  6. **
  7. ** © Copyright by GuntherSoft
  8. **
  9. ** File             : SnakeSYS:CPrgs/Utils/Move.c
  10. ** Created on       : Wednesday, 11.08.93 15:01:14
  11. ** Created by       : Kai Iske
  12. ** Current revision : V1.3
  13. **
  14. **
  15. ** Purpose
  16. ** -------
  17. **   - Small move utility which supports wildcards and doesn`t use
  18. **     Rename() nor Copy() nor anything similar...
  19. **
  20. ** Revision V1.3
  21. ** --------------
  22. ** created on Wednesday, 25.08.93 16:32:43  by  Kai Iske.   LogMessage :
  23. **   - UnLock Problem solved when doing recursive Dir-Moves
  24. **     This bug lead to "Object in use" error messages
  25. **
  26. ** Revision V1.2
  27. ** --------------
  28. ** created on Tuesday, 17.08.93 22:48:38  by  Kai Iske.   LogMessage :
  29. **   - Added CTRL-C checking
  30. **   - Added FORCE Flag in order to move read/deleteprotected or
  31. **     to overwrite a delete/writeprotected files
  32. **
  33. ** Revision V1.1
  34. ** --------------
  35. ** created on Monday, 16.08.93 22:53:34  by  Kai Iske.   LogMessage :
  36. **   - Added well known CLONE, DATES, COM, NOPRO,
  37. **     QUIET and NOREQ options also used by e.g. Rename
  38. **
  39. ** Revision V1.0
  40. ** --------------
  41. ** created on Wednesday, 11.08.93 15:01:14  by  Kai Iske.   LogMessage :
  42. **     --- Initial release ---
  43. **
  44. *********************************************************************************/
  45. #define REVISION "1.3"
  46. #define REVDATE  "25.08.93"
  47. #define REVTIME  "16:32:43"
  48. #define AUTHOR   "Kai Iske"
  49. #define VERNUM   1
  50. #define REVNUM   3
  51.  
  52. #include    <string.h>
  53. #include    <stdlib.h>
  54. #include    <exec/types.h>
  55. #include    <proto/exec.h>
  56. #include    <proto/dos.h>
  57. #include    <exec/memory.h>
  58. #include    <exec/execbase.h>
  59. #include    <dos/exall.h>
  60. #include    <dos/dos.h>
  61.  
  62.  
  63.  
  64. /**********************************************************************/
  65. /*                         Defines for Flags                          */
  66. /**********************************************************************/
  67. #define    CLONE        0x0001
  68. #define    DATES        0x0002
  69. #define    NOPRO        0x0004
  70. #define    COM        0x0008
  71. #define    QUIET        0x0010
  72. #define    FORCE        0x0020
  73.  
  74. #define    WATCHSIGS    SIGBREAKF_CTRL_C
  75.  
  76.  
  77.  
  78. /**********************************************************************/
  79. /*                      Static char definitions                       */
  80. /**********************************************************************/
  81. static    char    *Version    = "$VER: Move "REVISION" ("REVDATE")\0";
  82. static    char    *Template    = "FROM/M,TO/A,CLONE/S,DATES/S,NOPRO/S,COM/S,QUIET/S,NOREQ/S,FORCE/S";
  83. enum    {FROM_ARG, TO_ARG, CLONE_ARG, DATES_ARG, NOPRO_ARG, COM_ARG, QUIET_ARG, NOREQ_ARG, FORCE_ARG, LAST_ARG};
  84.  
  85.  
  86.  
  87. /**********************************************************************/
  88. /*                             Prototypes                             */
  89. /**********************************************************************/
  90. int    __saveds DoMove(void);
  91. BOOL    DoTheMove(char *FromFile, char *ToPath, BOOL PatternFrom, BPTR OutHandle, struct DOSBase *DOSBase, LONG Type, LONG Size, UWORD CopyFlags, LONG *HitMask);
  92. BOOL    DoMoveFile(char *FromFile, char *ToPath, char *Buffer, BPTR OutHandle, struct DOSBase *DOSBase, LONG Size, UWORD CopyFlags, LONG *HitMask);
  93.  
  94.  
  95. /**********************************************************************/
  96. /*                          The main program                          */
  97. /**********************************************************************/
  98. int __saveds DoMove(void)
  99. {
  100.     struct    FileInfoBlock    *FIB;
  101.     struct    ExecBase    *SysBase = *((struct ExecBase **)0x4L);
  102.     struct    DOSBase        *DOSBase;
  103.     struct    Process        *MyProc = (struct Process *)SysBase->ThisTask;
  104.     struct    RDArgs        *RDArgs;
  105.     struct    ExAllControl    *EAC;
  106.     struct    ExAllData    *EAB, *EAD;
  107.     APTR    *Args,
  108.         *OldWindow;
  109.     BPTR    DirLock,
  110.         OutHandle;
  111.     char    **FromPtr;
  112.     char    *ToPtr;
  113.     char    Pattern[256];
  114.     char    PathName[256];
  115.     char    Buffer[256];
  116.     LONG    HitMask;
  117.     UWORD    NumFrom = 0, PatternType, CopyFlags = 0;
  118.     BOOL    PatternFrom, GoOn = TRUE, Scanning;
  119.  
  120.         // Ignore startup from WB
  121.  
  122.     if(!(MyProc->pr_CLI))
  123.     {
  124.         struct    Message    *MyMsg;
  125.  
  126.         WaitPort(&MyProc->pr_MsgPort);
  127.         MyMsg = GetMsg(&MyProc->pr_MsgPort);
  128.         Disable();
  129.         ReplyMsg(MyMsg);
  130.         return(0);
  131.     }
  132.  
  133.         // Do the wild thing
  134.  
  135.     if((DOSBase = (struct DOSBase *)OpenLibrary("dos.library", 37)))
  136.     {
  137.         if((FIB = AllocVec(sizeof(struct FileInfoBlock), MEMF_CLEAR)))
  138.         {
  139.                 // Get buffer for ReadArgs()
  140.  
  141.             if((Args = AllocVec((LAST_ARG * sizeof(ULONG)), MEMF_CLEAR)))
  142.             {
  143.                     // Get structure for ExAll()
  144.  
  145.                 if((EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  146.                 {
  147.                         // Get buffer for ExAll()
  148.  
  149.                     if((EAB = AllocVec((sizeof(struct ExAllData)*20), MEMF_CLEAR)))
  150.                     {
  151.                             // Parse commandline
  152.  
  153.                         if((RDArgs = ReadArgs(Template, (ULONG *)Args, NULL)))
  154.                         {
  155.                                 // From and to really there ??
  156.  
  157.                             if(Args[FROM_ARG] && Args[TO_ARG])
  158.                             {
  159.                                 OutHandle    = Output();
  160.  
  161.                                     // Get Flags
  162.  
  163.                                 if(Args[CLONE_ARG])
  164.                                     CopyFlags    |=    CLONE;
  165.                                 if(Args[DATES_ARG])
  166.                                     CopyFlags    |=    DATES;
  167.                                 if(Args[NOPRO_ARG])
  168.                                     CopyFlags    |=    NOPRO;
  169.                                 if(Args[COM_ARG])
  170.                                     CopyFlags    |=    COM;
  171.                                 if(Args[QUIET_ARG])
  172.                                     CopyFlags    |=    QUIET;
  173.                                 if(Args[FORCE_ARG])
  174.                                     CopyFlags    |=    FORCE;
  175.  
  176.                                     // Check for NOREQ Option
  177.  
  178.                                 if(Args[NOREQ_ARG])
  179.                                 {
  180.                                     OldWindow        = MyProc->pr_WindowPtr;
  181.                                     MyProc->pr_WindowPtr    = (void *)(-1L);
  182.                                 }
  183.  
  184.                                     // Get pointers to Files
  185.  
  186.                                 FromPtr    = (char **)Args[FROM_ARG];
  187.                                 ToPtr    = (char *)Args[TO_ARG];
  188.  
  189.                                     // Count FROM entries
  190.  
  191.                                 while(*FromPtr++)
  192.                                     NumFrom++;
  193.  
  194.                                     // Restore FromPtr
  195.  
  196.                                 FromPtr    = (char **)Args[FROM_ARG];
  197.  
  198.                                     // Set pattern if there are more than 1
  199.                                     // FROM files or if the only FROM file
  200.                                     // is a pattern
  201.  
  202.                                 if(NumFrom > 1)
  203.                                     PatternFrom = TRUE;
  204.                                 else
  205.                                     PatternFrom = ParsePatternNoCase(*FromPtr, Pattern, 256);
  206.  
  207.                                     // If a pattern is used, check
  208.                                     // whether the dest really is a dir
  209.  
  210.                                 if(PatternFrom)
  211.                                 {
  212.                                         // Try to obtain a lock
  213.  
  214.                                     if((DirLock = Lock(ToPtr, ACCESS_READ)))
  215.                                     {
  216.                                             // Check file
  217.  
  218.                                         if(Examine(DirLock, FIB))
  219.                                         {
  220.                                                 // Get type of destination entry
  221.  
  222.                                             GoOn = (FIB->fib_DirEntryType > 0);
  223.  
  224.                                                 // If it`s not a directory (multiple files are to be moved)
  225.                                                 // issue an error
  226.  
  227.                                             if(!GoOn)
  228.                                                 FPuts(OutHandle, "\nMove : Multiple files may not be moved to a single file\n");
  229.                                         }
  230.                                         else
  231.                                         {
  232.                                                 // Examine() failed -> Abort
  233.  
  234.                                             GoOn = FALSE;
  235.                                             PrintFault(IoErr(), "\nMove ");
  236.                                         }
  237.  
  238.                                             // Unlock CheckDir
  239.  
  240.                                         UnLock(DirLock);
  241.                                     }
  242.                                     else
  243.                                     {
  244.                                             // If lock failed issue an error
  245.  
  246.                                         PrintFault(IoErr(), "\nMove ");
  247.                                         GoOn = FALSE;
  248.                                     }
  249.                                 }
  250.                                     // Loop for all source files
  251.  
  252.                                 while(NumFrom && GoOn)
  253.                                 {
  254.                                         // Check for CTRL-C
  255.  
  256.                                     if(GoOn)
  257.                                         HitMask    = CheckSignal(WATCHSIGS);
  258.  
  259.                                     if(!HitMask && GoOn)
  260.                                     {
  261.                                             // Check if this source is a pattern
  262.  
  263.                                         strcpy(Buffer, FilePart(*FromPtr));
  264.                                         strupr(Buffer);
  265.                                         PatternType = ParsePatternNoCase(Buffer, Pattern, 256);
  266.  
  267.                                             // It is a pattern
  268.  
  269.                                         if(PatternType == 1)
  270.                                         {
  271.                                                 // Create name of source
  272.  
  273.                                             strcpy(Buffer, *FromPtr);
  274.                                             *PathPart(Buffer)    = '\0';
  275.  
  276.                                                 // Get Lock for Source - Directory
  277.  
  278.                                             if((DirLock = Lock(Buffer, ACCESS_READ)))
  279.                                             {
  280.                                                     // Setup ExAllControl-Structure
  281.  
  282.                                                 EAC->eac_LastKey    = 0L;
  283.                                                 EAC->eac_MatchString    = Pattern;
  284.                                                 EAC->eac_MatchFunc    = NULL;
  285.  
  286.                                                 do
  287.                                                 {
  288.                                                         // Check for CTRL-C
  289.  
  290.                                                     if(GoOn)
  291.                                                         HitMask = CheckSignal(WATCHSIGS);
  292.  
  293.                                                     if(HitMask)
  294.                                                         GoOn = FALSE;
  295.  
  296.                                                         // Scan directory
  297.  
  298.                                                     Scanning = ExAll(DirLock, EAB, (20*sizeof(struct ExAllData)), ED_TYPE, EAC);
  299.  
  300.                                                         // Issue Error
  301.  
  302.                                                     if(GoOn && (!Scanning) && (IoErr() != ERROR_NO_MORE_ENTRIES))
  303.                                                     {
  304.                                                         PrintFault(IoErr(), "\nMove ");
  305.                                                         GoOn = FALSE;
  306.                                                     }
  307.  
  308.                                                         // End of Dir reached
  309.  
  310.                                                     if(EAC->eac_Entries == 0)
  311.                                                         Scanning = FALSE;
  312.                                                     else if(GoOn)
  313.                                                     {
  314.                                                         EAD    = EAB;
  315.  
  316.                                                         do
  317.                                                         {
  318.                                                                 // Check for CTRL-C
  319.  
  320.                                                             if(GoOn)
  321.                                                                 HitMask = CheckSignal(WATCHSIGS);
  322.  
  323.                                                             if(!HitMask && GoOn)
  324.                                                             {
  325.                                                                     // Createfilename for this file to be moved
  326.  
  327.                                                                 strcpy(PathName, *FromPtr);
  328.                                                                 *PathPart(PathName)    = '\0';
  329.                                                                 AddPart(PathName, EAD->ed_Name, 256);
  330.  
  331.                                                                     // Move file
  332.  
  333.                                                                 if((GoOn = DoTheMove(PathName, ToPtr, TRUE, OutHandle, DOSBase, EAD->ed_Type, EAD->ed_Size, CopyFlags, &HitMask)) && (EAD->ed_Type > 0))
  334.                                                                 {
  335.                                                                         // Delete directory after a succesful move
  336.  
  337.                                                                     if(!(GoOn = DeleteFile(PathName)))
  338.                                                                         PrintFault(IoErr(), "\nMove ");
  339.                                                                 }
  340.  
  341.                                                                 EAD    = EAD->ed_Next;
  342.                                                             }
  343.                                                             else
  344.                                                                 GoOn = FALSE;
  345.  
  346.                                                         } while(EAD && GoOn);
  347.                                                     }
  348.                                                 } while(Scanning);
  349.  
  350.                                                     // Unlock source directory
  351.  
  352.                                                 UnLock(DirLock);
  353.                                             }
  354.                                             else
  355.                                             {
  356.                                                     // Issue error, if dir could not be locked
  357.  
  358.                                                 PrintFault(IoErr(), "\nMove ");
  359.                                                 GoOn    = FALSE;
  360.                                             }
  361.                                         }
  362.                                             // No pattern
  363.  
  364.                                         else if(PatternType == 0)
  365.                                         {
  366.                                                 // Try to lock source file/dir
  367.  
  368.                                             if((DirLock = Lock(*FromPtr, ACCESS_READ)))
  369.                                             {
  370.                                                     // Examine this lock
  371.  
  372.                                                 if(Examine(DirLock, FIB))
  373.                                                 {
  374.                                                         // Unlock directory and do the move
  375.  
  376.                                                     UnLock(DirLock);
  377.                                                     if((GoOn = DoTheMove(*FromPtr, ToPtr, TRUE, OutHandle, DOSBase, FIB->fib_DirEntryType, FIB->fib_Size, CopyFlags, &HitMask)) && (FIB->fib_DirEntryType > 0))
  378.                                                     {
  379.                                                             // Delete dir after a succesfull move
  380.  
  381.                                                         if(!(GoOn = DeleteFile(*FromPtr)))
  382.                                                             PrintFault(IoErr(), "\nMove ");
  383.                                                     }
  384.                                                 }
  385.                                                 else
  386.                                                 {
  387.                                                         // Issue error on failed Examine()
  388.  
  389.                                                     PrintFault(IoErr(), "\nMove ");
  390.                                                     GoOn = FALSE;
  391.                                                     UnLock(DirLock);
  392.                                                 }
  393.                                             }
  394.                                             else
  395.                                             {
  396.                                                     // No Lock() no more moves
  397.  
  398.                                                 PrintFault(IoErr(), "\nMove ");
  399.                                                 GoOn = FALSE;
  400.                                             }
  401.                                         }
  402.  
  403.                                             // Error condition
  404.  
  405.                                         else
  406.                                         {
  407.                                             PrintFault(IoErr(), "\nMove ");
  408.                                             GoOn = FALSE;
  409.                                         }
  410.  
  411.                                         NumFrom--;
  412.                                         FromPtr++;
  413.                                     }
  414.                                     else
  415.                                         GoOn    = FALSE;
  416.                                 }
  417.                             }
  418.  
  419.                                 // Free ReadArgs
  420.  
  421.                             FreeArgs(RDArgs);
  422.                         }
  423.                         else
  424.                             PrintFault(IoErr(), "\nMove ");
  425.  
  426.                             // Free ExAll-Buffer
  427.  
  428.                         FreeVec(EAB);
  429.                     }
  430.                     else
  431.                         PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  432.  
  433.                         // Free ExAllControl Structure
  434.  
  435.                     FreeDosObject(DOS_EXALLCONTROL, (void *)EAC);
  436.                 }
  437.                 else
  438.                     PrintFault(IoErr(), "\nMove ");
  439.  
  440.                     // Free Argument Buffer
  441.  
  442.                 FreeVec(Args);
  443.             }
  444.             else
  445.                 PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  446.  
  447.             FreeVec(FIB);
  448.         }
  449.         else
  450.             PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  451.  
  452.             // Check for Abort-Signals
  453.  
  454.         if(HitMask && !(CopyFlags & QUIET))
  455.         {
  456.                 // Display appropriate message
  457.  
  458.             if(HitMask & SIGBREAKF_CTRL_C)
  459.                 FPuts(OutHandle, "\nMove ^C...\n");
  460.         }
  461.  
  462.             // Close DOSLibrary
  463.  
  464.         CloseLibrary((struct Library *)DOSBase);
  465.     }
  466.  
  467.         // Restore old window pointer (if any)
  468.  
  469.     if(OldWindow)
  470.         MyProc->pr_WindowPtr    = OldWindow;
  471.  
  472.  
  473.         // Depending on this flag return appropriate return code
  474.  
  475.     if(GoOn)
  476.         return(0);
  477.     else
  478.         return(10);
  479. }
  480.  
  481.  
  482.  
  483.  
  484. /**********************************************************************/
  485. /*                            Do the move                             */
  486. /**********************************************************************/
  487. BOOL DoTheMove(char *FromFile, char *ToPath, BOOL PatternFrom, BPTR OutHandle, struct DOSBase *DOSBase, LONG Type, LONG Size, UWORD CopyFlags, LONG *HitMask)
  488. {
  489.     struct    ExAllControl    *EAC;
  490.     struct    ExAllData    *EAB, *EAD;
  491.     char    NewDir[256];
  492.     char    Buffer[256];
  493.     UWORD    Len;
  494.     BPTR    DirLock;
  495.     BOOL    RetVal = TRUE, Scanning;
  496.  
  497.         // If a pattern is used print the name of the file to be moved
  498.  
  499.     if(PatternFrom && !(CopyFlags & QUIET))
  500.     {
  501.         strcpy(Buffer, FromFile);
  502.         strcat(Buffer, "...");
  503.         Write(OutHandle, " ", 1);
  504.         Write(OutHandle, Buffer, strlen(Buffer));
  505.     }
  506.  
  507.         // Is it a directory ???
  508.         // If yes, recursively loop for all entries within dir
  509.  
  510.     if(Type > 0)
  511.     {
  512.         strcpy(Buffer, FromFile);
  513.  
  514.             // Get length of from name
  515.  
  516.         Len    = strlen(Buffer);
  517.         if(Len)
  518.         {
  519.             if(Buffer[Len - 1] == '/')
  520.                 Buffer[Len - 1] = '\0';
  521.  
  522.                 // Copy dest name to buffer
  523.  
  524.             strcpy(NewDir, ToPath);
  525.  
  526.                 // Add name of from directory
  527.  
  528.             AddPart(NewDir, FilePart(Buffer), 256);
  529.  
  530.                 // Try to lock directory or
  531.                 // create it, if not existent
  532.  
  533.             if(!(DirLock = Lock(NewDir, ACCESS_READ)))
  534.             {
  535.                 if((DirLock = CreateDir(NewDir)) && PatternFrom && !(CopyFlags & QUIET))
  536.                     Write(OutHandle, " [created]...", 13);
  537.             }
  538.  
  539.                 // Got the destination directory ???
  540.  
  541.             if(DirLock)
  542.             {
  543.                     // Unlock Directory
  544.  
  545.                 UnLock(DirLock);
  546.  
  547.                     // Lock sourcedirectory
  548.  
  549.                 if((DirLock = Lock(Buffer, ACCESS_READ)))
  550.                 {
  551.                         // Get ExAll Control for recursive directory search
  552.  
  553.                     if((EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  554.                     {
  555.                             // Allocate buffer for move
  556.  
  557.                         if((EAB = AllocVec((20*sizeof(struct ExAllData)), MEMF_CLEAR)))
  558.                         {
  559.                             EAC->eac_LastKey    = 0L;
  560.                             EAC->eac_MatchString    = NULL;
  561.                             EAC->eac_MatchFunc    = NULL;
  562.  
  563.                             do
  564.                             {
  565.                                     // Check for CTRL-C
  566.  
  567.                                 if(RetVal)
  568.                                     (*HitMask) = CheckSignal(WATCHSIGS);
  569.  
  570.                                 if((*HitMask))
  571.                                     RetVal = FALSE;
  572.  
  573.                                     // Scan directory for entries
  574.  
  575.                                 Scanning = ExAll(DirLock, EAB, (20*sizeof(struct ExAllData)), ED_SIZE, EAC);
  576.  
  577.                                     // Check for an error
  578.  
  579.                                 if(RetVal && (!Scanning) && (IoErr() != ERROR_NO_MORE_ENTRIES))
  580.                                 {
  581.                                     PrintFault(IoErr(), "\nMove ");
  582.                                     RetVal = FALSE;
  583.                                 }
  584.  
  585.                                     // End of Dir reached
  586.  
  587.                                 if(EAC->eac_Entries == 0)
  588.                                     Scanning = FALSE;
  589.                                 else if(RetVal)
  590.                                 {
  591.                                     EAD = EAB;
  592.  
  593.                                     do
  594.                                     {
  595.                                             // Check for CTRL-C
  596.  
  597.                                         if(RetVal)
  598.                                             (*HitMask) = CheckSignal(WATCHSIGS);
  599.  
  600.                                         if(!(*HitMask) && RetVal)
  601.                                         {
  602.                                                 // Create filename of source
  603.  
  604.                                             strcpy(Buffer, FromFile);
  605.                                             AddPart(Buffer, EAD->ed_Name, 256);
  606.  
  607.                                                 // And start recursion
  608.  
  609.                                             if((RetVal = DoTheMove(Buffer, NewDir, FALSE, OutHandle, DOSBase, EAD->ed_Type, EAD->ed_Size, CopyFlags, HitMask)) && (EAD->ed_Type > 0))
  610.                                             {
  611.                                                     // if file moved was a dir, delete it
  612.  
  613.                                                 if(!(RetVal = DeleteFile(Buffer)))
  614.                                                     PrintFault(IoErr(), "\nMove ");
  615.                                             }
  616.  
  617.                                                 // Loop for all entries
  618.  
  619.                                             EAD = EAD->ed_Next;
  620.                                         }
  621.                                         else
  622.                                             RetVal = FALSE;
  623.  
  624.                                     } while(EAD && RetVal);
  625.                                 }
  626.                             } while(Scanning);
  627.  
  628.                                 // Free ExAll Buffer
  629.  
  630.                             FreeVec(EAB);
  631.                         }
  632.                         else
  633.                         {
  634.                             PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  635.                             RetVal = FALSE;
  636.                         }
  637.  
  638.                             // Free ExAllControl Structure
  639.  
  640.                         FreeDosObject(DOS_EXALLCONTROL, EAC);
  641.                     }
  642.                     else
  643.                     {
  644.                         PrintFault(IoErr(), "\nMove ");
  645.                         RetVal = FALSE;
  646.                     }
  647.  
  648.                     UnLock(DirLock);
  649.                 }
  650.                 else
  651.                 {
  652.                     PrintFault(IoErr(), "\nMove ");
  653.                     RetVal = FALSE;
  654.                 }
  655.             }
  656.             else
  657.             {
  658.                 PrintFault(IoErr(), "\nMove ");
  659.                 RetVal = FALSE;
  660.             }
  661.         }
  662.     }
  663.     else
  664.     {
  665.             // On a plain file -> Simply move it
  666.  
  667.         RetVal = DoMoveFile(FromFile, ToPath, Buffer, OutHandle, DOSBase, Size, CopyFlags, HitMask);
  668.     }
  669.  
  670.         // If there was a pattern (or a single directory)
  671.         // end the Move string
  672.  
  673.     if(PatternFrom && RetVal && !(CopyFlags & QUIET))
  674.         FPuts(OutHandle, " moved\n");
  675.  
  676.         // Return Code
  677.  
  678.     return(RetVal);
  679. }
  680.  
  681.  
  682.  
  683.  
  684.  
  685. /**********************************************************************/
  686. /*                      Ein File wirklich moven                       */
  687. /**********************************************************************/
  688. BOOL DoMoveFile(char *FromFile, char *ToPath, char *Buffer, BPTR OutHandle, struct DOSBase *DOSBase, LONG Size, UWORD CopyFlags, LONG *HitMask)
  689. {
  690.     struct    FileInfoBlock    *FIB;
  691.     BPTR    InFile, OutFile;
  692.     APTR    CopyBuffer;
  693.     char    DestName[256];
  694.     LONG    AvailSize, ReadSize;
  695.     BOOL    RetVal = TRUE, ErrCpy = FALSE, LoopCpy = TRUE;
  696.  
  697.     if((FIB = AllocVec(sizeof(struct FileInfoBlock), MEMF_CLEAR)))
  698.     {
  699.  
  700.         strcpy(DestName, ToPath);
  701.  
  702.             // Check, if destfile already exists
  703.             // If so, check if it`s a dir.
  704.             // Yes -> Copy with sourcename
  705.             // No -> Copy with given name
  706.  
  707.         if((OutFile = Lock(DestName, ACCESS_READ)))
  708.         {
  709.             if(Examine(OutFile, FIB))
  710.             {
  711.                     // If dest is a directory move with source name
  712.  
  713.                 if(FIB->fib_DirEntryType > 0)
  714.                     AddPart(DestName, FilePart(FromFile), 256);
  715.             }
  716.             else
  717.             {
  718.                     // No examine -> Use source filename
  719.  
  720.                 AddPart(DestName, FilePart(FromFile), 256);
  721.             }
  722.  
  723.             UnLock(OutFile);
  724.         }
  725.  
  726.             // Try to lock input file
  727.  
  728.         if((InFile = Lock(FromFile, ACCESS_READ)))
  729.         {
  730.                 // Get old protection bits, comment and filedate
  731.  
  732.             if(Examine(InFile, FIB))
  733.             {
  734.                     // In Force mode -> Force read and delete permissons
  735.                     // for input file
  736.  
  737.                 if(CopyFlags & FORCE)
  738.                     SetProtection(FromFile, ~(FIBF_OTR_READ|FIBF_OTR_DELETE|FIBF_READ|FIBF_DELETE));
  739.             }
  740.             else
  741.             {
  742.                 PrintFault(IoErr(), "\nMove ");
  743.                 RetVal = FALSE;
  744.             }
  745.  
  746.                 // If so, unlock
  747.  
  748.             UnLock(InFile);
  749.         }
  750.         else
  751.         {
  752.             PrintFault(IoErr(), "\nMove ");
  753.             RetVal = FALSE;
  754.         }
  755.  
  756.             // Open Input file
  757.  
  758.         if(RetVal && (InFile = Open(FromFile, MODE_OLDFILE)))
  759.         {
  760.                 // Outfile already there ??? and in force mode ???
  761.  
  762.             if((CopyFlags & FORCE) && ((OutFile = Lock(DestName, ACCESS_READ))))
  763.             {
  764.                     // Force delete and write permissons
  765.  
  766.                 UnLock(OutFile);
  767.                 SetProtection(DestName, ~(FIBF_OTR_WRITE|FIBF_OTR_DELETE|FIBF_WRITE|FIBF_DELETE));
  768.             }
  769.  
  770.                 // Open Output file
  771.  
  772.             if((OutFile = Open(DestName, MODE_NEWFILE)))
  773.             {
  774.                     // Get available size of memory
  775.  
  776.                 AvailSize    = AvailMem(MEMF_LARGEST);
  777.                 Size        = (Size > AvailSize) ? AvailSize : Size;
  778.  
  779.                     // Loop till we get a buffer
  780.  
  781.                 while(Size && !(CopyBuffer = AllocVec(Size, MEMF_CLEAR)))
  782.                     Size    -= 1024;
  783.  
  784.                 if(CopyBuffer)
  785.                 {
  786.                         // Loop for portions of the source file
  787.  
  788.                     while(RetVal && LoopCpy)
  789.                     {
  790.                             // Check for CTRL-C
  791.  
  792.                         if(RetVal)
  793.                             (*HitMask) = CheckSignal(WATCHSIGS);
  794.  
  795.                         if(!(*HitMask) && RetVal)
  796.                         {
  797.                                 // Read part of file
  798.  
  799.                             if((ReadSize = Read(InFile, CopyBuffer, Size)) > 0)
  800.                             {
  801.                                     // And write it back
  802.  
  803.                                 if(Write(OutFile, CopyBuffer, Size) == -1)
  804.                                 {
  805.                                     PrintFault(IoErr(), "\nMove ");
  806.                                     RetVal    = FALSE;
  807.                                     ErrCpy    = TRUE;
  808.                                 }
  809.                             }
  810.                             else
  811.                             {
  812.                                     // EOF ??? -> End copy
  813.  
  814.                                 if(ReadSize == 0)
  815.                                     LoopCpy    = FALSE;
  816.                                 else
  817.                                 {
  818.                                         // Otherwise issue error
  819.  
  820.                                     PrintFault(IoErr(), "\nMove ");
  821.                                     RetVal    = FALSE;
  822.                                     ErrCpy    = TRUE;
  823.                                 }
  824.                             }
  825.                         }
  826.                         else
  827.                             RetVal = FALSE;
  828.                     }
  829.  
  830.                         // Free Copy buffer
  831.  
  832.                     FreeVec(CopyBuffer);
  833.                 }
  834.                 else
  835.                 {
  836.                         // Issue error
  837.  
  838.                     PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  839.                     RetVal    = FALSE;
  840.                     ErrCpy    = TRUE;
  841.                 }
  842.  
  843.                     // Close outfile
  844.  
  845.                 Close(OutFile);
  846.             }
  847.             else
  848.             {
  849.                     // Issue error
  850.  
  851.                 PrintFault(IoErr(), "\nMove ");
  852.                 RetVal = FALSE;
  853.             }
  854.                 // Close InFile
  855.  
  856.             Close(InFile);
  857.         }
  858.         else
  859.         {
  860.                 // Issue error
  861.  
  862.             PrintFault(IoErr(), "\nMove ");
  863.             RetVal = FALSE;
  864.         }
  865.  
  866.             // Free FileInfo Block
  867.  
  868.         FreeVec(FIB);
  869.     }
  870.     else
  871.     {
  872.         PrintFault(ERROR_NO_FREE_STORE, "\nMove ");
  873.         RetVal = FALSE;
  874.     }
  875.  
  876.         // Error while copying ?? -> Remove Dest file
  877.  
  878.     if(ErrCpy)
  879.         DeleteFile(DestName);
  880.  
  881.         // No Error -> Remove Source file
  882.  
  883.     if(RetVal && !ErrCpy)
  884.     {
  885.         if(!(RetVal = DeleteFile(FromFile)))
  886.             PrintFault(IoErr(), "\nMove ");
  887.         else
  888.         {
  889.                 // Set bits etc. as requested
  890.  
  891.             if((CopyFlags & CLONE) || (CopyFlags & DATES))
  892.                 SetFileDate(DestName, &FIB->fib_Date);
  893.  
  894.             if((CopyFlags & CLONE) || (CopyFlags & COM))
  895.                 SetComment(DestName, FIB->fib_Comment);
  896.  
  897.             if(((CopyFlags & CLONE) && !(CopyFlags & NOPRO)) || (!(CopyFlags & CLONE) && !(CopyFlags & NOPRO)))
  898.                 SetProtection(DestName, FIB->fib_Protection);
  899.         }
  900.     }
  901.  
  902.  
  903.     return(RetVal);
  904. }
  905.