home *** CD-ROM | disk | FTP | other *** search
- /* UNBACK.C
-
- This is a program to speed up the process of restoring backup data from
- floppies.
-
- Written By Stephen Vermeulen, some code from an example called
- "TrackDisk" on Fish Disk 1 by Rob Peck. This code may be used
- to develop other Amiga applications.
-
- I wrote this because I got POed at th AmigaDOS Copy command not
- verifing that the data was written to disk correctly. Note that this
- only recovers one file per disk (but this is ok if you are using
- Matt Dillon's BackUp/Restore utility).
-
- Syntax is UNBACK drivenumber filename
- */
-
- #include <intuition/intuition.h>
- #include "exec/types.h"
- #include "exec/nodes.h"
- #include "exec/lists.h"
- #include "exec/memory.h"
- #include "exec/interrupts.h"
- #include "exec/ports.h"
- #include "exec/libraries.h"
- #include "exec/io.h"
- #include "exec/tasks.h"
- #include "exec/execbase.h"
- #include "exec/devices.h"
- #include "devices/trackdisk.h"
- #include "libraries/dos.h"
- #include <libraries/dosextens.h>
- #include <functions.h>
- #include <time.h>
-
- long _stack = 4000;
- long _priority = 0;
- long _BackGroundIO = 0;
- char *_procname = NULL;
-
- #define TD_READ CMD_READ
- #define BLOCKSIZE TD_SECTOR
- #define TRKSIZE NUMSECS*BLOCKSIZE
- #define NUMTRKS 160L
- #define BACK (('B' << 24L) + ('A' << 16L) + ('C' << 8L) + ((long) 'K'))
-
- SHORT error;
- struct MsgPort *diskport;
- struct IOExtTD *diskreq;
- BYTE *diskbuffer;
- SHORT testval;
-
- extern struct MsgPort *CreatePort();
- extern struct IORequest *CreateExtIO();
-
- ULONG diskChangeCount;
-
- ReadCyl(trk)
- SHORT trk;
- {
- diskreq->iotd_Req.io_Length = TRKSIZE;
- diskreq->iotd_Req.io_Data = (APTR) diskbuffer;
- /* show where to put the data when read */
- diskreq->iotd_Req.io_Command = ETD_READ;
- /* check that disk not changed before reading */
- diskreq->iotd_Count = diskChangeCount;
-
- /* convert from cylinder, head, sector to byte-offset value to get
- * right one (as dos and everyone else sees it)...*/
-
- /* driver reads one track at a time (head does not move for
- * 11 sequential sector reads
- */
-
- diskreq->iotd_Req.io_Offset = TRKSIZE * trk;
- DoIO(diskreq);
- return(0);
- }
-
- WriteCyl(trk)
- SHORT trk;
- {
- diskreq->iotd_Req.io_Length = TRKSIZE;
- diskreq->iotd_Req.io_Data = (APTR) diskbuffer;
- /* show where to put the data when read */
- diskreq->iotd_Req.io_Command = TD_FORMAT;
- /* check that disk not changed before reading */
- diskreq->iotd_Count = diskChangeCount;
-
- /* convert from cylinder, head, sector to byte-offset value to get
- * right one (as dos and everyone else sees it)...*/
-
- /* driver reads one track at a time (head does not move for
- * 11 sequential sector reads
- */
-
- diskreq->iotd_Req.io_Offset = TRKSIZE * trk;
- DoIO(diskreq);
- return(0);
- }
-
- MotorOn()
- {
- /* TURN ON DISK MOTOR ... old motor state is returned in io_Actual */
- diskreq->iotd_Req.io_Length = 1;
- /* this says motor is to be turned on */
- diskreq->iotd_Req.io_Command = TD_MOTOR;
- /* do something with the motor */
- DoIO(diskreq);
- return(0);
- }
-
- MotorOff()
- {
- diskreq->iotd_Req.io_Length = 0;
- /* says that motor is to be turned on */
- diskreq->iotd_Req.io_Command = TD_MOTOR;
- /* do something with the motor */
- DoIO(diskreq);
- return(0);
- }
-
- char *dnames[4] = { "DF0:", "DF1:", "DF2:", "DF3:" };
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- SHORT track,head,sector, i, j, ok, loaded;
- int k, usedrive, io;
- ULONG file;
- long dlen, chksum, *lptr, first, filelen, actlen;
-
- if ((argc != 3) && (argc != 2))
- {
- puts("Syntax: UNBACK DRIVE [filename]");
- puts("where drive is 0, 1, 2, 3 for DF0:, DF1:, DF2: or DF3:");
- return;
- }
- usedrive = atoi(argv[1]);
- if ((usedrive < 0) || (usedrive > 3))
- {
- puts("Drive number MUST be one of 0, 1, 2, or 3");
- return;
- }
- /** open the file
- **/
-
- if (argc == 3)
- {
- file = (ULONG) Open(argv[2], MODE_NEWFILE);
- if (!file)
- {
- puts("Could not open the file for writing.");
- return;
- }
- }
- else
- file = NULL;
-
- diskChangeCount = -1L;
- diskbuffer = (BYTE *) AllocMem(TRKSIZE, MEMF_CHIP | MEMF_PUBLIC);
- if (diskbuffer)
- {
- diskport = CreatePort(0L,0L);
- if (diskport)
- {
- diskreq = (struct IOExtTD *)CreateExtIO(diskport,
- (long) sizeof(struct IOExtTD));
-
- /* make an io request block for communicating with the disk */
- if (diskreq)
- {
- error = OpenDevice(TD_NAME, (long) usedrive, diskreq, 0L);
- if (!error)
- {
- dos_packet(DeviceProc(dnames[usedrive]), ACTION_INHIBIT, TRUE, 0L, 0L, 0L, 0L, 0L, 0L);
-
- /* ready to go, now wait for the user to do something */
-
- diskChangeCount = -1L;
- MotorOn();
-
- /** get the file length and then read the first
- 9*512 bytes (missing the 2 boot blocks...)
- less 4 bytes for the true file length
- **/
-
- for (track = 0; track < NUMTRKS; ++track ) /* tracks to copy */
- {
- io = 5;
- retry_track:
- ReadCyl(track);
- if (diskreq->iotd_Req.io_Error)
- {
- if (--io) goto retry_track;
- puts("Error reading. Aborting.");
- break;
- }
- if (track)
- {
- /** these tracks are all data...
- **/
-
- actlen = filelen;
- if (actlen > 11L * 512L)
- actlen = 11L*512L;
- if (-1L == Write(file, diskbuffer, actlen))
- {
- puts("Error writing to file. Aborted.");
- break;
- }
- }
- else
- {
- /** this track is special... **/
- /** get the file length and then read the first
- 9*512 bytes (missing the 2 boot blocks...)
- less 12 bytes for the true file length, datestamp,
- and filename length along with the filename
- **/
-
- lptr = (long *) diskbuffer;
- filelen = lptr[256];
- printf("File: %s saved on: %s", &lptr[259], ctime(&lptr[257]));
- if (!file) goto info_only;
- actlen = filelen;
- if (actlen > 9L * 512L - lptr[258] - 12L)
- actlen = 9L*512L - lptr[258] - 12L;
- if (-1L == Write(file, ((long) &lptr[259]) + lptr[258], actlen))
- {
- puts("Error writing to file. Aborted.");
- break;
- }
- }
- filelen -= actlen;
-
- /** read all data ? **/
-
- if (filelen <= 0L) break;
- }
- info_only:
- MotorOff();
- CloseDevice(diskreq);
- dos_packet(DeviceProc(dnames[usedrive]), ACTION_INHIBIT, FALSE, 0L, 0L, 0L, 0L, 0L, 0L);
- }
- DeleteExtIO(diskreq, (long) sizeof(struct IOExtTD));
- }
- DeletePort(diskport);
- }
- FreeMem(diskbuffer, TRKSIZE);
- }
- if (file) Close(file);
- } /* end of main */
-
-
-