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 / unback.c < prev   
C/C++ Source or Header  |  1989-11-27  |  7KB  |  257 lines

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