home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / modula2 / tutorial / programs / bakcopy.mod < prev    next >
Text File  |  1993-03-14  |  9KB  |  228 lines

  1. MODULE BakCopy;
  2.  
  3. (* This program is used to actually copy the files from the fixed  *)
  4. (* disk to the floppy disks.  It uses the file FULLDISK.LST as the *)
  5. (* basis for its copying.  That file is generated using the sister *)
  6. (* program BAKLIST, and after generation, it can be modified with  *)
  7. (* any text editor to allow elimination of any files or directories*)
  8. (* that you do not wish to back up.                                *)
  9. (*                                                                 *)
  10. (*            Copywrite (c) 1987 - Coronado Enterprises            *)
  11.  
  12. (* Note that this is a preliminary version of this example program *)
  13. (* and as such, it is not completely refined as it would need to   *)
  14. (* be for a full production system.  Since it was never intended   *)
  15. (* to compete with the full production backup systems available,   *)
  16. (* but was meant only to illustrate the method of building up a    *)
  17. (* significant sized program, it is considered to have attained    *)
  18. (* the original goal.  It can be used as a backup system if you    *)
  19. (* don't mind the following problems.                              *)
  20. (*                                                                 *)
  21. (* 1. The date and time of the files on the copy are the date and  *)
  22. (*    time that the copies are made, not the date and time of the  *)
  23. (*    original files.  The date and time of the original can be    *)
  24. (*    read and copied to the copy using interrupt 21 - function    *)
  25. (*    call 57H if you can figure out how to get the file handle.   *)
  26. (*                                                                 *)
  27. (* 2. This system does not copy hidden files.                      *)
  28. (*                                                                 *)
  29. (* 3. This system does not copy files that are too big to fit on   *)
  30. (*    one floppy disk.                                             *)
  31. (*                                                                 *)
  32. (* 4. The filesize and the room remaining on the disk are handled  *)
  33. (*    using floating point numbers instead of CARDINAL which would *)
  34. (*    be a much needed improvement.  The floating point numbers on *)
  35. (*    this system use enough significant digits to allow this,     *)
  36. (*    but changing to CARDINAL would be an improvement.  Keep in   *)
  37. (*    mind if you attempt this, that the upper limit on a CARDINAL *)
  38. (*    is 65535 so it would require the use of two CARDINALS for    *)
  39. (*    filesize and two for room on disk.                           *)
  40.  
  41. FROM InOut         IMPORT WriteString, WriteCard, WriteLn,
  42.                           Write, Read;
  43. FROM RealInOut     IMPORT WriteReal;
  44. FROM FileSystem    IMPORT Lookup, Close, File, Response, ReadByte;
  45. FROM Strings       IMPORT Copy, Insert, Delete;
  46. FROM DiskDirectory IMPORT CurrentDrive;
  47. FROM SYSTEM        IMPORT ADR;
  48. FROM DirHelps      IMPORT GetDiskStatistics, ChangeToDirectory,
  49.                           CopyFile, FileData, FileDataPointer,
  50.                           ReadFileStats;
  51.  
  52. TYPE CharArray = ARRAY[0..100] OF CHAR;
  53.  
  54. VAR  InputFile         : File;
  55.      SourceDrive       : CHAR;
  56.      SourceFile        : CharArray;
  57.      TargetDrive       : CHAR;
  58.      TargetFile        : CharArray;
  59.      InputLine         : CharArray;
  60.      WorkingDirectory  : CharArray;
  61.      Char              : CHAR;
  62.      Index             : CARDINAL;
  63.      SectorsPerCluster : CARDINAL;
  64.      FreeClusters      : CARDINAL;
  65.      BytesPerSector    : CARDINAL;
  66.      TotalClusters     : CARDINAL;
  67.      ErrorRet          : BOOLEAN;
  68.      ErrorCode         : CARDINAL;
  69.      FileSize          : REAL;
  70.      RoomOnDisk        : REAL;
  71.      RoomOnNewDisk     : REAL;
  72.      DataForFile       : FileData;
  73.      PointToData       : FileDataPointer;
  74.      DiskNumber        : CARDINAL;
  75.      EndOfCopy         : BOOLEAN;
  76.  
  77.  
  78. (* This procedure is used to read in one full line from the input  *)
  79. (* file.                                                           *)
  80.  
  81. PROCEDURE ReadALine;
  82. BEGIN
  83.    Index := 0;
  84.    REPEAT        (* Read one line of input data *)
  85.       ReadByte(InputFile,Char);
  86.       IF Char <> 15C THEN
  87.          InputLine[Index] := Char;
  88.          INC(Index);
  89.       END;
  90.    UNTIL (Index = 100) OR (Char = 12C) OR InputFile.eof;
  91.    InputLine[Index - 1] := 000C;
  92. END ReadALine;
  93.  
  94.  
  95.  
  96. (* This procedure calls the actual copying routine after it checks *)
  97. (* to see if there is enough room on the target floppy.  If there  *)
  98. (* is not, it requests a blank floppy to be loaded.                *)
  99.  
  100. PROCEDURE CopyTheFile;
  101. BEGIN
  102.    Delete(InputLine,0,1);                  (* Remove leading blank *)
  103.    SourceFile := InputLine;
  104.    Insert(SourceDrive,SourceFile,0);
  105.    Insert(':',SourceFile,1);
  106.    TargetFile := InputLine;
  107.    Insert(TargetDrive,TargetFile,0);
  108.    Insert(':',TargetFile,1);
  109.                            (* See if the file will fit on the disk *)
  110.    PointToData := ADR(DataForFile);
  111.    ReadFileStats(SourceFile,TRUE,PointToData,ErrorRet);
  112.    FileSize := PointToData^.Size;
  113.    GetDiskStatistics(TargetDrive,SectorsPerCluster,FreeClusters,
  114.                      BytesPerSector,TotalClusters);
  115.    RoomOnDisk := FLOAT(SectorsPerCluster) *
  116.                  FLOAT(FreeClusters) *
  117.                  FLOAT(BytesPerSector);
  118.    IF RoomOnDisk >= FileSize THEN
  119.       CopyFile(SourceFile,TargetFile,FileSize,ErrorCode);
  120.    ELSIF RoomOnNewDisk >= FileSize THEN
  121.       WriteString("Install a new disk, hit return to continue");
  122.       WriteString(", or hit Q to stop backup");
  123.       WriteLn;
  124.       Read(Char);
  125.       IF Char = 'Q' THEN
  126.          EndOfCopy := TRUE;
  127.       ELSE
  128.          INC(DiskNumber);
  129.          WriteString("Beginning disk number ");
  130.          WriteCard(DiskNumber,3);
  131.          WriteLn;
  132.          ChangeToDirectory(WorkingDirectory,TRUE,ErrorRet);
  133.          GetDiskStatistics(TargetDrive,SectorsPerCluster,FreeClusters,
  134.                            BytesPerSector,TotalClusters);
  135.          RoomOnDisk := FLOAT(SectorsPerCluster) *
  136.                        FLOAT(FreeClusters) *
  137.                        FLOAT(BytesPerSector);
  138.  
  139.          IF RoomOnDisk >= FileSize THEN
  140.             CopyFile(SourceFile,TargetFile,FileSize,ErrorCode);
  141.          ELSE
  142.             WriteString("File too big for this system");
  143.          END;
  144.       END;
  145.    ELSE
  146.       WriteString("File too big for this system");
  147.    END;
  148. END CopyTheFile;
  149.  
  150.  
  151.  
  152. (* This procedure makes the calls to change the directories of both*)
  153. (* the source and target directories.                              *)
  154.  
  155. PROCEDURE ChangeBothDirectories;
  156. BEGIN
  157.    Insert(SourceDrive,InputLine,0);
  158.    Insert(':',InputLine,1);
  159.    ChangeToDirectory(InputLine,FALSE,ErrorRet);
  160.    IF ErrorRet THEN
  161.       WriteString(InputLine);
  162.       WriteString("  Cannot change to source directory");
  163.       WriteLn;
  164.    END;
  165.    InputLine[0] := TargetDrive;
  166.    WorkingDirectory := InputLine;
  167.    ChangeToDirectory(InputLine,TRUE,ErrorRet);
  168.    IF ErrorRet THEN
  169.       WriteString(InputLine);
  170.       WriteString("  Cannot change to target directory");
  171.       WriteLn;
  172.    END;
  173. END ChangeBothDirectories;
  174.  
  175.  
  176.  
  177. BEGIN (* Main program *)
  178.    DiskNumber := 1;
  179.    EndOfCopy := FALSE;
  180.    WriteString("Enter the target drive, one letter ---> ");
  181.    Read(TargetDrive);
  182.    TargetDrive := CAP(TargetDrive);
  183.    Write(TargetDrive);
  184.    WriteLn;
  185.    WriteString("Beginning disk number   1");
  186.    WriteLn;
  187.    GetDiskStatistics(TargetDrive, SectorsPerCluster, FreeClusters,
  188.                      BytesPerSector, TotalClusters);
  189.    IF BytesPerSector > 0 THEN                 (* Valid drive found *)
  190.       RoomOnNewDisk := FLOAT(SectorsPerCluster) *
  191.                        FLOAT(TotalClusters) *
  192.                        FLOAT(BytesPerSector);
  193.       Copy("C:\FULLDISK.LST",0,100,SourceFile);
  194.       CurrentDrive(SourceDrive);       (* Get current drive letter *)
  195.       SourceFile[0] := SourceDrive;  (* Open FULLDISK.LST for read *)
  196.       Lookup(InputFile,SourceFile,FALSE);
  197.       IF InputFile.res = done THEN
  198.          LOOP
  199.             ReadALine;
  200.             IF InputFile.eof THEN
  201.                EXIT;
  202.             ELSE
  203.                IF InputLine[0] = ' ' THEN              (* Filename *)
  204.                   CopyTheFile;
  205.                   IF EndOfCopy THEN EXIT END;
  206.                ELSIF InputLine[0] = 000C THEN
  207.                               (* Empty line, not a directory entry *)
  208.                ELSE                                   (* Directory *)
  209.                   ChangeBothDirectories;
  210.                   WriteString(" Directory ---> ");
  211.                   WriteString(InputLine);
  212.                   WriteLn;
  213.                END
  214.             END;
  215.          END; (* LOOP *)
  216.          Close(InputFile);
  217.       ELSE
  218.          WriteString("FULLDISK.LST not available for reading.");
  219.          WriteLn;
  220.          WriteString("Program terminated");
  221.          WriteLn;
  222.       END;
  223.       WriteString("End of Backup copy program");
  224.       WriteLn;
  225.    END; (* Drive test *)
  226. END BakCopy.
  227.  
  228.