
/*
 *  SKIPFILEMARK.C
 */

#include <exec/types.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <devices/scsidisk.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>

typedef unsigned char ubyte;

typedef struct MsgPort	MsgPort;
typedef struct IOStdReq IOStdReq;
typedef struct SCSICmd	SCSICmd;

typedef struct SCSIReq {
    IOStdReq sr_Req;
    SCSICmd  sr_Cmd;
} SCSIReq;

MsgPort *IoSink;
SCSIReq Ios;

char *ErrorAry[] = {
    "No Sense",
    "Recovered Error",
    "Not Ready",
    "Medium Error",
    "Hardware Error",
    "Illegal Request",
    "Unit Attention",
    "Data Protect",
    "Blank Check",
    "Vendor Specific",
    "Copy Aborted",
    "Aborted Command",
    "Equal (search_data)",
    "Volume Overflow",
    "MisCompare",
    "Reserved",
    "Unknown Error"
};

void myexit(void);

main(ac, av)
char *av[];
{
    char skipCmd[] = { 0x11, 0x01, 0x00, 0x00, 0x01, 0x00 };
    int error;

    atexit(myexit);

    IoSink = CreatePort(NULL, 0);

    if (SCSIOpen("scsi.device", 4) < 0) {
	puts("Unable to open scsi.device");
	exit(20);
    }
    if (ac == 2) {
	long n = strtol(av[1], NULL, 0);
	skipCmd[2] = n >> 16;
	skipCmd[3] = n >> 8;
	skipCmd[4] = n;
    }
    if (error = DoSCSI(skipCmd, NULL, 0, SCSIF_READ, NULL))
	printf("error %d %s\n", error, ErrorAry[(error >= 0 && error < 16) ? error : 16]);
    return(0);
}

void
myexit(void)
{
    SCSIClose();
    if (IoSink)
	DeletePort(IoSink);
}


int
SCSIOpen(devName, unitNo)
char *devName;
long unitNo;
{
    int error;

    Ios.sr_Req.io_Message.mn_ReplyPort = IoSink;
    if (error = OpenDevice(devName, unitNo, &Ios.sr_Req, 0))
	error = -1;
    return(error);
}

int
SCSIClose()
{
    if (Ios.sr_Req.io_Device) {
	CloseDevice(&Ios);
	Ios.sr_Req.io_Device = NULL;
    }
}

int
DoSCSI(cmd, buf, bytes, flags, len)
char *cmd;
char *buf;
long bytes;
ubyte flags;
long *len;
{
    static ubyte senseCmd[] = { 0x03, 0x00, 0x00, 0x00, 20, 0 };
    SCSIReq *ios = &Ios;
    char senseBuf[20];
    int error;

    ios->sr_Cmd.scsi_Command   = cmd;
    ios->sr_Cmd.scsi_CmdLength = 6;
    ios->sr_Cmd.scsi_Data   = buf;
    ios->sr_Cmd.scsi_Length = bytes;
    ios->sr_Cmd.scsi_Flags  = flags;

    ios->sr_Req.io_Command = 28;
    ios->sr_Req.io_Data    = &ios->sr_Cmd;
    ios->sr_Req.io_Length  = sizeof(ios->sr_Cmd);

    error = DoIO(&ios->sr_Req);
    if (len)
	*len = ios->sr_Cmd.scsi_Actual;

    switch(error) {
    case 0:
	break;
    case HFERR_BadStatus:
	ios->sr_Cmd.scsi_Command   = senseCmd;
	ios->sr_Cmd.scsi_CmdLength = 6;
	ios->sr_Cmd.scsi_Data	= (UWORD *)senseBuf;
	ios->sr_Cmd.scsi_Length = sizeof(senseBuf);
	ios->sr_Cmd.scsi_Flags	= SCSIF_READ;

	if (DoIO(&ios->sr_Req)) {
	    error = -256;
	    break;
	}
	if (ios->sr_Cmd.scsi_Actual < 4) {
	    error = -257;
	    break;
	}
	error = senseBuf[2];
	break;
    default:
	error = -error;
	break;
    }
    return(error);
}

