home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff284.lzh / Back / back.c < prev    next >
C/C++ Source or Header  |  1989-11-27  |  8KB  |  260 lines

  1. /* BACK.C
  2.  
  3.    Written By Stephen Vermeulen, some code from an example called
  4.    "TrackDisk" on Fish Disk 1 by Rob Peck.  This code may be used
  5.    to develop other Amiga applications.
  6.  
  7.   This is a program to speed up the process of saving backup data to
  8.   floppies and to add a verify feature to ensure the data gets there...
  9.   and stays there...  I wrote this because I got POed at th AmigaDOS
  10.   Copy command not verifing that the data was written to disk correctly.
  11.   Also this program (with verify) is still faster than the DOS Copy
  12.   command (without verify).  Note that this only stores one file
  13.   per disk (but this is ok if you are using Matt Dillon's BackUp/Restore
  14.   utility).
  15.  
  16.   Syntax is BACK filename drivenumber
  17.  
  18.   The back file is a straight foward copy of the original file onto
  19.   the floppy starting with the THIRD block of track 0.  There are a
  20.   few bytes used for header info (total number of file bytes, number of
  21.   name bytes, date stamp and the original filename
  22. */
  23.  
  24. #include <intuition/intuition.h>
  25. #include "exec/types.h"
  26. #include "exec/nodes.h"
  27. #include "exec/lists.h"
  28. #include "exec/memory.h"
  29. #include "exec/interrupts.h"
  30. #include "exec/ports.h"
  31. #include "exec/libraries.h"
  32. #include "exec/io.h"
  33. #include "exec/tasks.h"
  34. #include "exec/execbase.h"
  35. #include "exec/devices.h"
  36. #include "devices/trackdisk.h"
  37. #include "libraries/dos.h"
  38. #include <libraries/dosextens.h>
  39. #include <functions.h>
  40. #include <stdio.h>
  41. #include <time.h>
  42.  
  43. long _stack = 4000;
  44. long _priority = 0;
  45. long _BackGroundIO = 0;
  46. char *_procname = NULL;
  47.  
  48. #define TD_READ CMD_READ
  49. #define BLOCKSIZE TD_SECTOR
  50. #define TRKSIZE NUMSECS*BLOCKSIZE
  51. #define NUMTRKS 160L
  52. #define BACK (('B' << 24L) + ('A' << 16L) + ('C' << 8L) + ((long) 'K'))
  53.  
  54. SHORT error;
  55. struct MsgPort *diskport;
  56. struct IOExtTD *diskreq;
  57. BYTE *diskbuffer;
  58. SHORT testval;
  59.  
  60. extern struct MsgPort *CreatePort();
  61. extern struct IORequest *CreateExtIO();
  62.  
  63. ULONG diskChangeCount;
  64.  
  65. ReadCyl(trk)
  66. SHORT trk;
  67. {
  68.         diskreq->iotd_Req.io_Length = TRKSIZE;
  69.         diskreq->iotd_Req.io_Data = (APTR) diskbuffer;
  70.                 /* show where to put the data when read */
  71.         diskreq->iotd_Req.io_Command = ETD_READ;
  72.                 /* check that disk not changed before reading */
  73.         diskreq->iotd_Count = diskChangeCount;
  74.  
  75.         /* convert from cylinder, head, sector to byte-offset value to get
  76.          * right one (as dos and everyone else sees it)...*/
  77.  
  78.         /* driver reads one track at a time (head does not move for
  79.          * 11 sequential sector reads
  80.          */
  81.  
  82.         diskreq->iotd_Req.io_Offset = TRKSIZE * trk;
  83.         DoIO(diskreq);
  84.         return(0);
  85. }
  86.  
  87. WriteCyl(trk)
  88. SHORT trk;
  89. {
  90.         diskreq->iotd_Req.io_Length = TRKSIZE;
  91.         diskreq->iotd_Req.io_Data = (APTR) diskbuffer;
  92.                 /* show where to put the data when read */
  93.         diskreq->iotd_Req.io_Command = TD_FORMAT;
  94.                 /* check that disk not changed before reading */
  95.         diskreq->iotd_Count = diskChangeCount;
  96.  
  97.         /* convert from cylinder, head, sector to byte-offset value to get
  98.          * right one (as dos and everyone else sees it)...*/
  99.  
  100.         /* driver reads one track at a time (head does not move for
  101.          * 11 sequential sector reads
  102.          */
  103.  
  104.         diskreq->iotd_Req.io_Offset = TRKSIZE * trk;
  105.         DoIO(diskreq);
  106.         return(0);
  107. }
  108.  
  109. MotorOn()
  110. {
  111.         /* TURN ON DISK MOTOR ... old motor state is returned in io_Actual */
  112.         diskreq->iotd_Req.io_Length = 1;
  113.         /* this says motor is to be turned on */
  114.         diskreq->iotd_Req.io_Command = TD_MOTOR;
  115.         /* do something with the motor */
  116.         DoIO(diskreq);
  117.         return(0);
  118. }
  119.  
  120. MotorOff()
  121. {
  122.         diskreq->iotd_Req.io_Length = 0;
  123.         /* says that motor is to be turned on */
  124.         diskreq->iotd_Req.io_Command = TD_MOTOR;
  125.         /* do something with the motor */
  126.         DoIO(diskreq);
  127.         return(0);
  128. }
  129.  
  130. char *dnames[4] = { "DF0:", "DF1:", "DF2:", "DF3:" };
  131.  
  132. main(argc, argv)
  133. int argc;
  134. char *argv[];
  135. {
  136.   SHORT track,head,sector, i, j, ok, loaded;
  137.   int   k, usedrive;
  138.   ULONG file;
  139.   long dlen, chksum, *lptr, first, filelen;
  140.   struct FileInfoBlock *fib;
  141.  
  142.   fib = (struct FileInfoBlock *) AllocMem((long) sizeof(struct FileInfoBlock),
  143.                                            MEMF_PUBLIC);
  144.   if (!fib) return;
  145.   if (argc != 3)
  146.   {
  147.     puts("Syntax:  BACK filename DRIVE");
  148.     puts("where drive is 0, 1, 2, 3 for DF0:, DF1:, DF2: or DF3:");
  149.     return;
  150.   }
  151.   usedrive = atoi(argv[2]);
  152.   if ((usedrive < 0) || (usedrive > 3))
  153.   {
  154.     puts("Drive number MUST be one of 0, 1, 2, or 3");
  155.     return;
  156.   }
  157.   /** open the file, get the file length
  158.   **/
  159.  
  160.   file = (ULONG) Lock(argv[1], ACCESS_READ);
  161.   if (!file)
  162.   {
  163.     puts("Could not read the file");
  164.     return;
  165.   }
  166.   Examine(file, fib);
  167.   filelen = fib->fib_Size;
  168.   UnLock(file);
  169.   if (filelen > 22L*512L*80L - 2L*512L - strlen(argv[1]) - 1L - 12L)
  170.   {
  171.     puts("File is too large to fit on a floppy.");
  172.     FreeMem(fib, (long) sizeof(struct FileInfoBlock));
  173.     return;
  174.   }
  175.   file = (ULONG) Open(argv[1], MODE_OLDFILE);
  176.   if (!file)
  177.   {
  178.     puts("Could not read the file");
  179.     return;
  180.   }
  181.   diskChangeCount = -1L;
  182.   diskbuffer = (BYTE *) AllocMem(TRKSIZE, MEMF_CHIP | MEMF_PUBLIC);
  183.   if (diskbuffer)
  184.   {
  185.     diskport = CreatePort(0L,0L);
  186.     if (diskport)
  187.     {
  188.       diskreq = (struct IOExtTD *)CreateExtIO(diskport,
  189.             (long) sizeof(struct IOExtTD));
  190.  
  191.       /* make an io request block for communicating with the disk */
  192.       if (diskreq)
  193.       {
  194.         error = OpenDevice(TD_NAME, (long) usedrive, diskreq, 0L);
  195.         if (!error)
  196.         {
  197.           dos_packet(DeviceProc(dnames[usedrive]), ACTION_INHIBIT, TRUE, 0L, 0L, 0L, 0L, 0L, 0L);
  198.           puts("Press RETURN to proceed, `garbage' RETURN to abort");
  199.           fgets(diskbuffer, 80, stdin);
  200.           if (diskbuffer[0] != 10) goto abort_now;
  201.  
  202.           /* ready to go, now wait for the user to do something */
  203.  
  204.           diskChangeCount = -1L;
  205.           MotorOn();
  206.           lptr = (long *) diskbuffer;
  207.           for (i = 0; i < 256; ++i) lptr[i] = BACK;
  208.           track = 0;
  209.  
  210.           /** get the file length and then read the first
  211.               9*512 bytes (missing the 2 boot blocks...)
  212.               less 4 bytes for the true file length
  213.            **/
  214.  
  215.           lptr[256] = filelen;
  216.           lptr[257] = time(NULL);
  217.           lptr[258] = strlen(argv[1]) + 1;
  218.           CopyMem(argv[1], &lptr[259], lptr[258]);
  219.  
  220.           Read(file, ((long) &lptr[259]) + lptr[258], 9L*512L - lptr[258] - 12L);
  221.           filelen -= 9L*512L - lptr[258] - 12L;
  222.           while (track < NUMTRKS) /* tracks to copy */
  223.           {
  224.             WriteCyl(track);
  225.             if (diskreq->iotd_Req.io_Error)
  226.             {
  227.               puts("Error writing.  Aborting.");
  228.               break;
  229.             }
  230.             /** now do verify pass... **/
  231.             ReadCyl(track);
  232.             if (diskreq->iotd_Req.io_Error)
  233.             {
  234.               puts("Error verifing.  Aborting.");
  235.               break;
  236.             }
  237.             /** read all data ? **/
  238.             if (filelen <= 0L) break;
  239.             /** get more data **/
  240.             Read(file, diskbuffer, 11L*512L);
  241.             filelen -= 11L*512L;
  242.             track++;
  243.           }
  244.           MotorOff();
  245.           CloseDevice(diskreq);
  246. abort_now:
  247.           dos_packet(DeviceProc(dnames[usedrive]), ACTION_INHIBIT, FALSE, 0L, 0L, 0L, 0L, 0L, 0L);
  248.         }
  249.         DeleteExtIO(diskreq, (long) sizeof(struct IOExtTD));
  250.       }
  251.       DeletePort(diskport);
  252.     }
  253.     FreeMem(diskbuffer, TRKSIZE);
  254.   }
  255.   Close(file);
  256.   FreeMem(fib, (long) sizeof(struct FileInfoBlock));
  257. }       /* end of main */
  258.  
  259.  
  260.