home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
disks
/
disk450.lzh
/
Tabu
/
tabu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-03
|
31KB
|
1,129 lines
#include "exec/types.h"
#include "exec/ports.h"
#include "exec/libraries.h"
#include "exec/io.h"
#include "exec/tasks.h"
#include "exec/execbase.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"
#include "workbench/workbench.h"
#include "workbench/startup.h"
#include "devices/scsidisk.h"
#include "stdio.h"
#include "time.h"
#include "functions.h"
#define RZ_BMAGIC 0x525a4d42
#define RZ_CMAGIC 0x525a4d43
#define RZ_SCSI "HardFrame.device"
#define RZ_DISK 000
#define RZ_TAPE 001
#define RZ_BLKS 128
#define RZ_BYTS 512
#define RZ_IOR struct IORequest
extern struct ExecBase *SysBase;
struct Library *IconBase;
void dsk2tap();
void tapelst();
void tap2dsk();
long bk_create(char *name);
void bk_d2t();
void bk_extract();
void bk_t2d();
long bk_write(struct FileInfoBlock *fib);
long dk_capacity();
long dk_close();
long dk_init();
long dk_read(long lba,long len);
long dk_write(long lba,long len);
void tmconv(struct DateStamp *date,char *dstr,char *tstr);
long tp_close();
long tp_eof();
long tp_init();
long tp_read(long len);
long tp_rewind();
long tp_sense();
long tp_write(long len);
long disk = RZ_DISK;
long tape = RZ_TAPE;
char scsi[] = RZ_SCSI;
long nest;
char refname[256];
UBYTE dkcmd[32];
UBYTE tpcmd[32];
UWORD data[RZ_BLKS * RZ_BYTS / 2];
ULONG *ldata = (ULONG *)data;
UBYTE *bdata = (UBYTE *)data;
UBYTE *dptr;
struct MsgPort dkmp = {{0,0,NT_MSGPORT,0,0},0,SIGB_SINGLE,0,{0,0,0,0,0}};
struct IOStdReq dkior = {{{0,0,NT_MESSAGE,0,0},&dkmp,0},0,0,0,0,0,0,0,0,0};
struct SCSICmd dksc;
struct MsgPort tpmp = {{0,0,NT_MSGPORT,0,0},0,SIGB_SINGLE,0,{0,0,0,0,0}};
struct IOStdReq tpior = {{{0,0,NT_MESSAGE,0,0},&tpmp,0},0,0,0,0,0,0,0,0,0};
struct SCSICmd tpsc;
struct WBStartup *wbsm;
struct WBArg *wba;
struct DiskObject *dobj;
union FHeader
{
struct FHBlock
{
ULONG magic;
long nest;
struct FileInfoBlock fib;
} fhb;
UBYTE fhbuf[sizeof(struct FHBlock)];
} fhdr;
struct FileInfoBlock *gfib = &(fhdr.fhb.fib);
/* ---------------------------------------------------------------------- */
main(long argc, char **argv)
{
long i;
long err;
long func;
char *cptr;
struct FileLock *olddir;
fprintf(stderr,"\ntabu - QIC tape backup utility\n");
fprintf(stderr,"Copyright 1990 - Roy C. Sigsbey\n\n");
if (argc == 0)
{
if ((IconBase = OpenLibrary("icon.library",0)) == NULL)
{
fprintf(stderr,"tabu: Icon library open failed, bye\n");
fprintf(stderr,"tabu finished, Press RETURN when ready.\n");
getchar();
exit(1);
}
else
{
wbsm = (struct WBStartup *)argv;
wba = wbsm->sm_ArgList;
olddir = CurrentDir((struct FileLock *)wba->wa_Lock);
dobj = GetDiskObject(wba->wa_Name);
err = 0;
if ((cptr = FindToolType(dobj->do_ToolTypes,"OPER")) != NULL)
{
switch(cptr[0])
{
case 'B':
case 'b':
func = 1;
break;
case 'C':
case 'c':
func = 2;
break;
case 'L':
case 'l':
func = 3;
break;
case 'R':
case 'r':
func = 4;
break;
case 'X':
case 'x':
func = 5;
break;
default:
err = 1;
break;
}
}
else err = 1;
if ((cptr = FindToolType(dobj->do_ToolTypes,"NAME")) != NULL)
strcpy(refname,cptr);
else refname[0] = '\0';
if ((cptr = FindToolType(dobj->do_ToolTypes,"LIST")) != NULL)
{
if (freopen(cptr,"w",stdout) == NULL) err = 1;
}
if ((cptr = FindToolType(dobj->do_ToolTypes,"SCSI")) != NULL)
{
strcpy(scsi,cptr);
}
if ((cptr = FindToolType(dobj->do_ToolTypes,"DISK")) != NULL)
{
if (sscanf(cptr,"%3d",&disk) != 1) err = 1;
}
if ((cptr = FindToolType(dobj->do_ToolTypes,"TAPE")) != NULL)
{
if (sscanf(cptr,"%3d",&tape) != 1) err = 1;
}
CurrentDir(olddir);
CloseLibrary(IconBase);
}
}
else
{
err = 0;
func = 0;
refname[0] = '\0';
for (i = 1; i < argc; i++)
{
if (argv[i][0] == '-')
{
switch (argv[i][1])
{
case 'B':
case 'b':
func = 1;
break;
case 'C':
case 'c':
func = 2;
break;
case 'D':
case 'd':
if (sscanf(&(argv[i][2]),"%3d",&disk) != 1) err = 1;
break;
case 'L':
case 'l':
func = 3;
break;
case 'R':
case 'r':
func = 4;
break;
case 'S':
case 's':
strcpy(scsi,&(argv[i][2]));
break;
case 'T':
case 't':
if (sscanf(&(argv[i][2]),"%3d",&tape) != 1) err = 1;
break;
case 'X':
case 'x':
func = 5;
break;
default:
err = 1;
break;
}
}
else strcpy(refname,argv[i]);
}
}
if (err != 0) func = 0;
switch (func)
{
case 1:
bk_d2t();
break;
case 2:
dsk2tap();
break;
case 3:
tapelst();
break;
case 4:
bk_t2d();
break;
case 5:
tap2dsk();
break;
default:
fprintf(stderr,
"usage: tabu [-ddsk] [-sscsi] [-ttap] -b|c|l|r|x [name]\n");
fprintf(stderr," -b = backup by blocks to tape\n");
fprintf(stderr," -c = create backup to tape\n");
fprintf(stderr," -d = dsk is scsi address for disk\n");
fprintf(stderr," -l = list tape contents\n");
fprintf(stderr," -r = restore by blocks from tape\n");
fprintf(stderr," -s = scsi is scsi device name\n");
fprintf(stderr," -t = tap is scsi address for tape\n");
fprintf(stderr," -x = extract from tape\n");
fprintf(stderr," name = reference name (req'd - c or x)\n");
fprintf(stderr,"tabu.info ToolTypes may be set as follows:\n");
fprintf(stderr," OPER=B backup\n");
fprintf(stderr," OPER=C create\n");
fprintf(stderr," OPER=L list\n");
fprintf(stderr," OPER=R restore\n");
fprintf(stderr," OPER=X extract\n");
fprintf(stderr," NAME=name reference name (req'd - C or X)\n");
fprintf(stderr," LIST=name list to file or printer\n");
fprintf(stderr," DISK=nnn disk scsi address\n");
fprintf(stderr," TAPE=nnn tape scsi address\n");
fprintf(stderr," SCSI=name scsi device name\n");
}
fprintf(stderr,"tabu finished, Press RETURN when ready.\n");
getchar();
exit(0);
}
/* ---------------------------------------------------------------------- */
void dsk2tap()
{
time_t timer;
if (strlen(refname) == 0)
{
fprintf(stderr,"tabu: reference name required for create\n");
return;
}
nest = 0;
dptr = bdata;
if (tp_init()) return;
if (bdata[8] & 0x10)
{
fprintf(stderr,"tabu: tape is write protected\n");
tp_close();
return;
}
time(&timer);
printf("\ntabu: backup %s\n",ctime(&timer));
if (bk_create(refname))
{
tp_close();
return;
}
if (dptr != bdata)
{
if (tp_write(((long)(dptr - bdata) / RZ_BYTS)))
{
tp_close();
return;
}
}
tp_eof();
tp_close();
return;
}
/* ---------------------------------------------------------------------- */
void tapelst()
{
long i;
long first_time;
char datestr[16];
char timestr[16];
if (tp_init()) return;
first_time = 1;
tpsc.scsi_Actual = RZ_BYTS * RZ_BLKS;
while (tpsc.scsi_Actual == (RZ_BYTS * RZ_BLKS))
{
if (tp_read(RZ_BLKS))
{
tp_close();
return;
}
if (first_time)
{
if ((bdata[0] != 'R') || (bdata[1] != 'Z') || (bdata[2] != 'M'))
{
fprintf(stderr,"tabu: tape is not a tabu backup\n");
break;
}
if (bdata[3] == 'B')
{
fprintf(stderr,"tabu: tape is a tabu disk image backup\n");
fprintf(stderr," backup date = %s\n",&(bdata[4]));
break;
}
first_time = 0;
}
for (dptr = bdata; dptr < (bdata + tpsc.scsi_Actual); dptr += RZ_BYTS)
{
if ((dptr[0] == 'R') && (dptr[1] == 'Z') && (dptr[2] == 'M') &&
(dptr[3] == 'C'))
{
for (i = 0; i < sizeof(struct FHBlock); i++)
fhdr.fhbuf[i] = dptr[i];
tmconv(&(gfib->fib_Date),datestr,timestr);
printf("l - %08x %s %s %9d ",gfib->fib_Protection,datestr,
timestr,gfib->fib_Size);
for (i = 0; i < fhdr.fhb.nest; i++)
printf("| ");
printf("%s\n",gfib->fib_FileName);
}
}
}
tp_close();
return;
}
/* ---------------------------------------------------------------------- */
void tap2dsk()
{
struct FileInfoBlock *fib;
struct FileLock *fl,*ofl;
/* access refname which must be a directory or disk */
if (strlen(refname) == 0)
{
fprintf(stderr,"tabu: reference name required for extract\n");
return;
}
fib = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0);
if (fib == NULL)
{
fprintf(stderr,"tabu: tap2dsk, fib allocation failed\n");
return;
}
if ((fl = Lock(refname,ACCESS_READ)) == NULL)
{
FreeMem(fib,sizeof(struct FileInfoBlock));
fprintf(stderr,"tabu: tap2dsk, Lock of %s failed\n",refname);
return;
}
if (!Examine(fl,fib))
{
UnLock(fl);
FreeMem(fib,sizeof(struct FileInfoBlock));
fprintf(stderr,"tabu: tap2dsk, Examine of %s failed\n",refname);
return;
}
if(fib->fib_DirEntryType <= 0)
{
UnLock(fl);
FreeMem(fib,sizeof(struct FileInfoBlock));
fprintf(stderr,"tabu: reference for extract must be a directory\n");
return;
}
/* initialize tape */
if (tp_init())
{
UnLock(fl);
FreeMem(fib,sizeof(struct FileInfoBlock));
return;
}
/* cd to refname and ready to extract tape contents into it */
ofl = CurrentDir(fl);
tpsc.scsi_Actual = RZ_BYTS * RZ_BLKS;
dptr = bdata + tpsc.scsi_Actual;
/* extract tape contents */
nest = 0;
bk_extract();
/* done - cd back to where we were before */
ofl = CurrentDir(ofl);
UnLock(fl);
FreeMem(fib,sizeof(struct FileInfoBlock));
tp_close();
return;
}
/* ---------------------------------------------------------------------- */
long bk_create(char *name)
{
long i;
long fin;
struct FileInfoBlock *fib;
struct FileLock *fl,*ofl;
char datestr[16];
char timestr[16];
/* access the named object */
fib = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0);
if (fib == NULL)
{
fprintf(stderr,"tabu: bk_create, fib allocation failed\n");
return 1;
}
if ((fl = Lock(name,ACCESS_READ)) == NULL)
{
fprintf(stderr,"tabu: bk_create, Lock of %s failed\n",name);
FreeMem(fib,sizeof(struct FileInfoBlock));
return 1;
}
if (!Examine(fl,fib))
{
fprintf(stderr,"tabu: bk_create, Examine of %s failed\n",name);
UnLock(fl);
FreeMem(fib,sizeof(struct FileInfoBlock));
return 1;
}
/* Don't write disk device block to tape */
if (name[strlen(name) - 1] == ':') nest--;
else
{
/* print line describing current object name */
tmconv(&(fib->fib_Date),datestr,timestr);
printf("c - %08x %s %s %9d ",fib->fib_Protection,datestr,timestr,
fib->fib_Size);
for (i = 0; i < nest; i++)
printf("| ");
printf("%s\n",fib->fib_FileName);
/* build tape image of FileInfoBlock and write it to tape */
fhdr.fhb.magic = RZ_CMAGIC;
fhdr.fhb.nest = nest;
gfib->fib_DiskKey = fib->fib_DiskKey;
gfib->fib_DirEntryType = fib->fib_DirEntryType;
strcpy(gfib->fib_FileName,fib->fib_FileName);
for (i = (strlen(gfib->fib_FileName) + 1); i < 108; i++)
gfib->fib_FileName[i] = '\0';
gfib->fib_Protection = fib->fib_Protection;
gfib->fib_EntryType = fib->fib_EntryType;
gfib->fib_Size = fib->fib_Size;
gfib->fib_NumBlocks = fib->fib_NumBlocks;
gfib->fib_Date.ds_Days = fib->fib_Date.ds_Days;
gfib->fib_Date.ds_Minute = fib->fib_Date.ds_Minute;
gfib->fib_Date.ds_Tick = fib->fib_Date.ds_Tick;
for (i = 0; i < 80; i++)
gfib->fib_Comment[i] = fib->fib_Comment[i];
for (i = 0; i < 36; i++)
gfib->fib_Reserved[i] = fib->fib_Reserved[i];
for (i = 0; i < RZ_BYTS; i++)
{
if (i < sizeof(struct FHBlock)) dptr[i] = fhdr.fhbuf[i];
else dptr[i] = 0x00;
}
dptr += RZ_BYTS;
if (dptr >= (bdata + (RZ_BLKS * RZ_BYTS)))
{
dptr = bdata;
if (tp_write(RZ_BLKS))
{
UnLock(fl);
FreeMem(fib,sizeof(struct FileInfoBlock));
return 1;
}
}
}
/* if object is a directory: */
if(fib->fib_DirEntryType > 0)
{
nest++;
ofl = CurrentDir(fl);
fin = 0;
while (fin == 0)
{
if (ExNext(fl,fib))
{
if (bk_create(fib->fib_FileName)) fin = 2;
}
else
{
if ((fin = IoErr()) != ERROR_NO_MORE_ENTRIES)
{
fprintf(stderr,"tabu: ExNext error = %d\n",fin);
fin = 2;
}
else fin = 1;
}
}
ofl = CurrentDir(ofl);
nest--;
}
/* else it is a file: */
else
{
fin = 1;
if (bk_write(fib)) fin++;
}
/* done with this object */
UnLock(fl);
FreeMem(fib,sizeof(struct FileInfoBlock));
return --fin;
}
/* ---------------------------------------------------------------------- */
void bk_d2t()
{
long size;
time_t timer;
if (dk_init()) return;
if (tp_init())
{
dk_close();
return;
}
ldata[0] = RZ_BMAGIC;
time(&timer);
strcpy(&(bdata[4]),ctime(&timer));
if (tp_write(1))
{
tp_close();
dk_close();
return;
}
dksc.scsi_Actual = RZ_BYTS * RZ_BLKS;
for (size = 0; dksc.scsi_Actual == (RZ_BYTS * RZ_BLKS);
size += dksc.scsi_Actual)
{
if (dk_read((size / RZ_BYTS),RZ_BLKS)) break;
if (tp_write(dksc.scsi_Actual / RZ_BYTS)) break;
}
fprintf(stderr,"tabu: backup bytes = %d\n",size);
tp_eof();
tp_close();
dk_close();
}
/* ---------------------------------------------------------------------- */
void bk_extract()
{
long i;
long wrsz;
long timer;
char namestr[256];
char datestr[16];
char timestr[16];
struct FileLock *fl,*ofl;
struct FileHandle *fhndl;
/* normal exit is nest level change or end of tape */
while (1)
{
/* ready next data block from tape */
if (dptr >= bdata + tpsc.scsi_Actual)
{
if (tpsc.scsi_Actual != (RZ_BYTS * RZ_BLKS)) return;
if (tp_read(RZ_BLKS)) return;
dptr = bdata;
}
/* copy tape block to header area */
for (i = 0; i < sizeof(struct FHBlock); i++)
fhdr.fhbuf[i] = dptr[i];
/* this had better be header block, not data block */
if (fhdr.fhb.magic != RZ_CMAGIC)
{
fprintf(stderr,"tabu: tape is not tabu file image backup\n");
return;
}
/* this item is a sibling to a higher nest level (lower number) */
if (fhdr.fhb.nest < nest) return;
/* we should never have a nest jump greater than one */
if (fhdr.fhb.nest > nest)
{
fprintf(stderr,"tabu: bk_extract, header nest error\n");
return;
}
/* List header block being processed */
tmconv(&(gfib->fib_Date),datestr,timestr);
printf("x - %08x %s %s %9d ",gfib->fib_Protection,datestr,timestr,
gfib->fib_Size);
for (i = 0; i < fhdr.fhb.nest; i++)
printf("| ");
printf("%s\n",gfib->fib_FileName);
/* set up name for SetDate fexecl call */
sprintf(namestr,"\"%s\"",gfib->fib_FileName);
/* Directory header block processing */
if(gfib->fib_DirEntryType > 0)
{
dptr += RZ_BYTS;
if ((fl = Lock(gfib->fib_FileName,ACCESS_READ)) == NULL)
{
if ((fl = CreateDir(gfib->fib_FileName)) == NULL)
{
fprintf(stderr,"tabu: CreateDir failed for %s\n",
gfib->fib_FileName);
dptr = bdata;
tpsc.scsi_Actual = 0;
return;
}
}
ofl = CurrentDir(fl);
nest++;
bk_extract();
nest--;
ofl = CurrentDir(ofl);
UnLock(fl);
SetProtection(gfib->fib_FileName,gfib->fib_Protection);
SetComment(gfib->fib_FileName,gfib->fib_Comment);
fexecl("SetDate","SetDate",namestr,datestr,timestr,NULL);
}
/* File block(s) processing */
else
{
/* File header block */
if ((dptr += RZ_BYTS) >= bdata + tpsc.scsi_Actual)
{
if (tpsc.scsi_Actual != (RZ_BYTS * RZ_BLKS))
{
fprintf(stderr,
"tabu: extract, tape eof before file size satisfied\n");
return;
}
if (tp_read(RZ_BLKS)) return;
dptr = bdata;
}
if ((fl = Lock(gfib->fib_FileName,ACCESS_WRITE)) == NULL)
{
if ((fhndl = Open(gfib->fib_FileName,MODE_NEWFILE))
== NULL)
{
fprintf(stderr,"tabu: bk_extract, Open failed for %s\n",
gfib->fib_FileName);
dptr = bdata;
tpsc.scsi_Actual = 0;
return;
}
}
else
{
UnLock(fl);
if ((fhndl = Open(gfib->fib_FileName,MODE_READWRITE))
== NULL)
{
fprintf(stderr,"tabu: bk_extract, Open failed for %s\n",
gfib->fib_FileName);
dptr = bdata;
tpsc.scsi_Actual = 0;
return;
}
}
/* File data block(s) */
for (i = gfib->fib_Size; i > 0; i -= RZ_BYTS)
{
if (i >= RZ_BYTS) wrsz = RZ_BYTS;
else wrsz = i;
if (Write(fhndl,(char *)dptr,wrsz) != wrsz)
{
fprintf(stderr,"tabu: bk_extract, file data write failed\n");
Close(fhndl);
SetProtection(gfib->fib_FileName,gfib->fib_Protection);
SetComment(gfib->fib_FileName,gfib->fib_Comment);
fexecl("SetDate","SetDate",namestr,datestr,timestr,NULL);
dptr = bdata;
tpsc.scsi_Actual = 0;
return;
}
if ((dptr += RZ_BYTS) >= (bdata + tpsc.scsi_Actual))
{
if (tpsc.scsi_Actual != (RZ_BYTS * RZ_BLKS))
{
if ((i - RZ_BYTS) > 0) fprintf(stderr,
"tabu: extract, tape eof before file size satisfied\n");
Close(fhndl);
SetProtection(gfib->fib_FileName,gfib->fib_Protection);
SetComment(gfib->fib_FileName,gfib->fib_Comment);
fexecl("SetDate","SetDate",namestr,datestr,timestr,NULL);
return;
}
if (tp_read(RZ_BLKS))
{
Close(fhndl);
SetProtection(gfib->fib_FileName,gfib->fib_Protection);
SetComment(gfib->fib_FileName,gfib->fib_Comment);
fexecl("SetDate","SetDate",namestr,datestr,timestr,NULL);
return;
}
dptr = bdata;
}
}
Close(fhndl);
SetProtection(gfib->fib_FileName,gfib->fib_Protection);
SetComment(gfib->fib_FileName,gfib->fib_Comment);
fexecl("SetDate","SetDate",namestr,datestr,timestr,NULL);
}
}
}
/* ---------------------------------------------------------------------- */
void bk_t2d()
{
long size;
if (tp_init()) return;
if (tp_read(1))
{
tp_close();
return;
}
if (ldata[0] != RZ_BMAGIC)
{
fprintf(stderr,"tabu: tape is not a tabu disk image backup\n");
tp_close();
return;
}
fprintf(stderr,"tabu: backup date = %s\n",&(bdata[4]));
if (dk_init())
{
tp_close();
return;
}
tpsc.scsi_Actual = RZ_BYTS * RZ_BLKS;
for (size = 0; tpsc.scsi_Actual == (RZ_BYTS * RZ_BLKS);
size += tpsc.scsi_Actual)
{
if (tp_read(RZ_BLKS)) break;
if (dk_write((size / RZ_BYTS),(tpsc.scsi_Actual / RZ_BYTS))) break;
}
fprintf(stderr,"tabu: restore bytes = %d\n",size);
dk_close();
tp_close();
}
/* ---------------------------------------------------------------------- */
long bk_write(struct FileInfoBlock *fib)
{
long recd;
long remn;
long totl;
struct FileHandle *fhndl;
if ((fhndl = Open(fib->fib_FileName,MODE_OLDFILE)) == NULL)
{
fprintf(stderr,"tabu: file Open error = %d\n",IoErr());
return 1;
}
totl = 0;
remn = (RZ_BYTS * RZ_BLKS) - (long)(dptr - bdata);
while ((recd = Read(fhndl,(char *)dptr,remn)) == remn)
{
dptr = bdata;
if (tp_write(RZ_BLKS))
{
Close(fhndl);
return 1;
}
totl += recd;
remn = (RZ_BYTS * RZ_BLKS);
}
if (recd != 0)
{
if (recd > 0)
{
totl += recd;
for (; (recd % RZ_BYTS) != 0; recd++)
dptr[recd] = 0x00;
dptr += recd;
if (dptr >= (bdata + (RZ_BLKS * RZ_BYTS)))
{
dptr = bdata;
if (tp_write(RZ_BLKS))
{
Close(fhndl);
return 1;
}
}
}
else
{
fprintf(stderr,"tabu: file Read error = %d\n",IoErr());
Close(fhndl);
return 1;
}
}
Close(fhndl);
if (totl != fib->fib_Size)
{
fprintf(stderr,"tabu: size error, expected %d, received %d\n",
fib->fib_Size,totl);
return 1;
}
return 0;
}
/* ---------------------------------------------------------------------- */
long dk_capacity()
{
dksc.scsi_Data = data;
dksc.scsi_Length = 8;
dksc.scsi_Command = dkcmd;
dksc.scsi_CmdLength = 10;
dksc.scsi_Flags = SCSIF_READ;
dkcmd[0] = 0x25; /* read capacity command */
dkcmd[1] = 0x00;
dkcmd[2] = 0x00;
dkcmd[3] = 0x00;
dkcmd[4] = 0x00;
dkcmd[5] = 0x00;
dkcmd[6] = 0x00;
dkcmd[7] = 0x00;
dkcmd[8] = 0x00;
dkcmd[9] = 0x00;
if (DoIO((RZ_IOR *)&dkior))
{
fprintf(stderr,"tabu: dk_capacity, DoIO error = %d\n",dkior.io_Error);
return 1;
}
return 0;
}
/* ---------------------------------------------------------------------- */
long dk_close()
{
CloseDevice((RZ_IOR *)&dkior);
}
/* ---------------------------------------------------------------------- */
long dk_init()
{
long i;
if (FindName(&SysBase->DeviceList,scsi) == NULL)
{
fprintf(stderr,"tabu: Device %s not found\n",scsi);
return 1;
}
dkmp.mp_SigTask = (struct Task *)FindTask(NULL);
NewList(&dkmp.mp_MsgList);
if (OpenDevice(scsi,disk,(RZ_IOR *)&dkior,0))
{
fprintf(stderr,"tabu: Device %s open failed.\n",scsi);
return 1;
}
dkior.io_Command = HD_SCSICMD;
dkior.io_Length = sizeof(dksc);
dkior.io_Data = (APTR) &dksc;
return 0;
}
/* ---------------------------------------------------------------------- */
long dk_read(long lba,long len)
{
dksc.scsi_Data = data;
dksc.scsi_Length = len * RZ_BYTS;
dksc.scsi_Command = dkcmd;
dksc.scsi_CmdLength = 6;
dksc.scsi_Flags = SCSIF_READ;
dkcmd[0] = 0x08; /* read command */
dkcmd[1] = (lba & 0x1f0000) >> 16; /* MSB logical block address */
dkcmd[2] = (lba & 0xff00) >> 8; /* logical block address */
dkcmd[3] = lba & 0xff; /* LSB logical block address */
dkcmd[4] = len & 0xff; /* number of blocks */
dkcmd[5] = 0x00;
if (DoIO((RZ_IOR *)&dkior))
{
fprintf(stderr,"tabu: dk_read, DoIO error = %d\n",dkior.io_Error);
return 1;
}
return 0;
}
/* ---------------------------------------------------------------------- */
long dk_write(long lba,long len)
{
dksc.scsi_Data = data;
dksc.scsi_Length = len * RZ_BYTS;
dksc.scsi_Command = dkcmd;
dksc.scsi_CmdLength = 6;
dksc.scsi_Flags = SCSIF_WRITE;
dkcmd[0] = 0x0a; /* write command */
dkcmd[1] = (lba & 0x1f0000) >> 16; /* MSB logical block address */
dkcmd[2] = (lba & 0xff00) >> 8; /* logical block address */
dkcmd[3] = lba & 0xff; /* LSB logical block address */
dkcmd[4] = len & 0xff; /* number of blocks */
dkcmd[5] = 0x00;
if (DoIO((RZ_IOR *)&dkior))
{
fprintf(stderr,"tabu: dk_write, DoIO error = %d\n",dkior.io_Error);
return 1;
}
return 0;
}
/* ---------------------------------------------------------------------- */
void tmconv(struct DateStamp *date,char *dstr,char *tstr)
{
long timer;
struct tm *tptr;
timer = (date->ds_Days + 2922) * 86400;
timer += date->ds_Minute * 60;
timer += date->ds_Tick / TICKS_PER_SECOND;
tptr = localtime((time_t *)(&timer));
switch (tptr->tm_mon)
{
case 0:
strcpy(tstr,"Jan");
break;
case 1:
strcpy(tstr,"Feb");
break;
case 2:
strcpy(tstr,"Mar");
break;
case 3:
strcpy(tstr,"Apr");
break;
case 4:
strcpy(tstr,"May");
break;
case 5:
strcpy(tstr,"Jun");
break;
case 6:
strcpy(tstr,"Jul");
break;
case 7:
strcpy(tstr,"Aug");
break;
case 8:
strcpy(tstr,"Sep");
break;
case 9:
strcpy(tstr,"Oct");
break;
case 10:
strcpy(tstr,"Nov");
break;
case 11:
strcpy(tstr,"Dec");
break;
}
sprintf(dstr,"%02d-%s-%02d",tptr->tm_mday,tstr,tptr->tm_year);
sprintf(tstr,"%02d:%02d:%02d",tptr->tm_hour,tptr->tm_min,tptr->tm_sec);
return;
}
/* ---------------------------------------------------------------------- */
long tp_close()
{
tp_rewind();
CloseDevice((RZ_IOR *)&tpior);
fprintf(stderr,"tabu finished, Press RETURN when ready.\n");
getchar();
exit(1);
}
/* ---------------------------------------------------------------------- */
long tp_eof()
{
tpsc.scsi_Data = NULL;
tpsc.scsi_Length = 0;
tpsc.scsi_Command = tpcmd;
tpsc.scsi_CmdLength = 6;
tpsc.scsi_Flags = 0;
tpcmd[0] = 0x10; /* write filemark command */
tpcmd[1] = 0;
tpcmd[2] = 0; /* MSB Number of filemarks */
tpcmd[3] = 0; /* Number of filemarks */
tpcmd[4] = 2; /* LSB Number of filemarks */
tpcmd[5] = 0;
if (DoIO((RZ_IOR *)&tpior))
{
fprintf(stderr,"tabu: tp_eof, DoIO error = %d\n",tpior.io_Error);
return 1;
}
return 0;
}
/* ---------------------------------------------------------------------- */
long tp_init()
{
if (FindName(&SysBase->DeviceList,scsi) == NULL)
{
fprintf(stderr,"tabu: Device %s not found\n",scsi);
return 1;
}
tpmp.mp_SigTask = (struct Task *)FindTask(NULL);
NewList(&tpmp.mp_MsgList);
if (OpenDevice(scsi,tape,(RZ_IOR *)&tpior,0))
{
fprintf(stderr,"tabu: Device %s open failed.\n",scsi);
return 1;
}
tpior.io_Command = HD_SCSICMD;
tpior.io_Length = sizeof(tpsc);
tpior.io_Data = (APTR) &tpsc;
if (tp_sense())
{
tp_close();
return 1;
}
if (bdata[8] & 0x40)
{
fprintf(stderr,"tabu: No tape in drive!\n");
return 1;
}
if (tp_rewind())
{
tp_close();
return 1;
}
return 0;
}
/* ---------------------------------------------------------------------- */
long tp_read(long len)
{
tpsc.scsi_Data = data;
tpsc.scsi_Length = len * RZ_BYTS;
tpsc.scsi_Command = tpcmd;
tpsc.scsi_CmdLength = 6;
tpsc.scsi_Flags = SCSIF_READ;
tpcmd[0] = 0x08; /* read command */
tpcmd[1] = 0x01;
tpcmd[2] = (len & 0xff0000) >> 16; /* MSB number of blocks */
tpcmd[3] = (len & 0xff00) >> 8; /* number of blocks */
tpcmd[4] = len & 0xff; /* LSB number of blocks */
tpcmd[5] = 0x00;
if (DoIO((RZ_IOR *)&tpior))
{
fprintf(stderr,"tabu: tp_read, DoIO error = %d\n",tpior.io_Error);
return 1;
}
return 0;
}
/* ---------------------------------------------------------------------- */
long tp_rewind()
{
tpsc.scsi_Data = NULL;
tpsc.scsi_Length = 0;
tpsc.scsi_Command = tpcmd;
tpsc.scsi_CmdLength = 6;
tpsc.scsi_Flags = 0;
tpcmd[0] = 0x01; /* rewind command */
tpcmd[1] = 0;
tpcmd[2] = 0;
tpcmd[3] = 0;
tpcmd[4] = 0;
tpcmd[5] = 0;
if (DoIO((RZ_IOR *)&tpior))
{
fprintf(stderr,"tabu: tp_rewind, DoIO error = %d\n",tpior.io_Error);
return 1;
}
return 0;
}
/* ---------------------------------------------------------------------- */
long tp_sense()
{
tpsc.scsi_Data = data;
tpsc.scsi_Length = 14;
tpsc.scsi_Command = tpcmd;
tpsc.scsi_CmdLength = 6;
tpsc.scsi_Flags = SCSIF_READ;
tpcmd[0] = 0x03; /* sense command */
tpcmd[1] = 0x00;
tpcmd[2] = 0x00;
tpcmd[3] = 0x00;
tpcmd[4] = 0x0e; /* number of sense bytes to fetch */
tpcmd[5] = 0x00;
if (DoIO((RZ_IOR *)&tpior))
{
fprintf(stderr,"tabu: tp_sense, DoIO error = %d\n",tpior.io_Error);
return 1;
}
return 0;
}
/* ---------------------------------------------------------------------- */
long tp_write(long len)
{
tpsc.scsi_Data = data;
tpsc.scsi_Length = len * RZ_BYTS;
tpsc.scsi_Command = tpcmd;
tpsc.scsi_CmdLength = 6;
tpsc.scsi_Flags = SCSIF_WRITE;
tpcmd[0] = 0x0a; /* write command */
tpcmd[1] = 0x01;
tpcmd[2] = (len & 0xff0000) >> 16; /* MSB number of blocks */
tpcmd[3] = (len & 0xff00) >> 8; /* number of blocks */
tpcmd[4] = len & 0xff; /* LSB number of blocks */
tpcmd[5] = 0x00;
if (DoIO((RZ_IOR *)&tpior))
{
fprintf(stderr,"tabu: tp_write, DoIO error = %d\n",tpior.io_Error);
return 1;
}
return 0;
}
/* end of code ---------------------------------------------------------- */