home *** CD-ROM | disk | FTP | other *** search
- /* BACK.C
-
- 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.
-
- This is a program to speed up the process of saving backup data to
- floppies and to add a verify feature to ensure the data gets there...
- and stays there... I wrote this because I got POed at th AmigaDOS
- Copy command not verifing that the data was written to disk correctly.
- Also this program (with verify) is still faster than the DOS Copy
- command (without verify). Note that this only stores one file
- per disk (but this is ok if you are using Matt Dillon's BackUp/Restore
- utility).
-
- Syntax is BACK filename drivenumber
-
- The back file is a straight foward copy of the original file onto
- the floppy starting with the THIRD block of track 0. There are a
- few bytes used for header info (total number of file bytes, number of
- name bytes, date stamp and the original 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 <stdio.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;
- ULONG file;
- long dlen, chksum, *lptr, first, filelen;
- struct FileInfoBlock *fib;
-
- fib = (struct FileInfoBlock *) AllocMem((long) sizeof(struct FileInfoBlock),
- MEMF_PUBLIC);
- if (!fib) return;
- if (argc != 3)
- {
- puts("Syntax: BACK filename DRIVE");
- puts("where drive is 0, 1, 2, 3 for DF0:, DF1:, DF2: or DF3:");
- return;
- }
- usedrive = atoi(argv[2]);
- if ((usedrive < 0) || (usedrive > 3))
- {
- puts("Drive number MUST be one of 0, 1, 2, or 3");
- return;
- }
- /** open the file, get the file length
- **/
-
- file = (ULONG) Lock(argv[1], ACCESS_READ);
- if (!file)
- {
- puts("Could not read the file");
- return;
- }
- Examine(file, fib);
- filelen = fib->fib_Size;
- UnLock(file);
- if (filelen > 22L*512L*80L - 2L*512L - strlen(argv[1]) - 1L - 12L)
- {
- puts("File is too large to fit on a floppy.");
- FreeMem(fib, (long) sizeof(struct FileInfoBlock));
- return;
- }
- file = (ULONG) Open(argv[1], MODE_OLDFILE);
- if (!file)
- {
- puts("Could not read the file");
- return;
- }
- 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);
- puts("Press RETURN to proceed, `garbage' RETURN to abort");
- fgets(diskbuffer, 80, stdin);
- if (diskbuffer[0] != 10) goto abort_now;
-
- /* ready to go, now wait for the user to do something */
-
- diskChangeCount = -1L;
- MotorOn();
- lptr = (long *) diskbuffer;
- for (i = 0; i < 256; ++i) lptr[i] = BACK;
- track = 0;
-
- /** 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
- **/
-
- lptr[256] = filelen;
- lptr[257] = time(NULL);
- lptr[258] = strlen(argv[1]) + 1;
- CopyMem(argv[1], &lptr[259], lptr[258]);
-
- Read(file, ((long) &lptr[259]) + lptr[258], 9L*512L - lptr[258] - 12L);
- filelen -= 9L*512L - lptr[258] - 12L;
- while (track < NUMTRKS) /* tracks to copy */
- {
- WriteCyl(track);
- if (diskreq->iotd_Req.io_Error)
- {
- puts("Error writing. Aborting.");
- break;
- }
- /** now do verify pass... **/
- ReadCyl(track);
- if (diskreq->iotd_Req.io_Error)
- {
- puts("Error verifing. Aborting.");
- break;
- }
- /** read all data ? **/
- if (filelen <= 0L) break;
- /** get more data **/
- Read(file, diskbuffer, 11L*512L);
- filelen -= 11L*512L;
- track++;
- }
- MotorOff();
- CloseDevice(diskreq);
- abort_now:
- 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);
- }
- Close(file);
- FreeMem(fib, (long) sizeof(struct FileInfoBlock));
- } /* end of main */
-
-
-