Imported Upstream version 1.3.11
[debian/mtx] / scsitape.c
index 1ff389295eea1d7100917a41aa9a363d28e3b623..8a7b2ca85f33475b6f599f93047e3503472ed819 100644 (file)
@@ -1,8 +1,8 @@
 /* Copyright 2001 Enhanced Software Technologies Inc.
  *   Released under terms of the GNU General Public License as
  * required by the license on 'mtxl.c'.
- * $Date: 2001/06/05 17:10:27 $
- * $Revision: 1.1.1.1 $
+ * $Date: 2007-03-24 18:14:01 -0700 (Sat, 24 Mar 2007) $
+ * $Revision: 166 $
  */
 
 /* This is a generic SCSI tape control program. It operates by
 /*#define DEBUG 1 */
 
 /* 
-   Commands:
-         setblk <n> -- set the block size to <n>
-         fsf <n> -- go forward by <n> filemarks
-         bsf <n> -- go backward by <n> filemarks
-         eod  -- go to end of data
-         rewind -- rewind back to start of data
-         eject  -- rewind, then eject the tape. 
-        erase  -- (short) erase the tape (we have no long erase)
-         mark <n> -- write <n> filemarks.
-         seek <n> -- seek to position <n>.
-
-        write <blksize> <-- write blocks from stdin to the tape 
-         read  [<blksize>] [<#blocks/#bytes>] -- read blocks from tape, write to stdout. 
-
-   See the 'tapeinfo' program for status info about the tape drive.
+       Commands:
+               setblk <n> -- set the block size to <n>
+               fsf <n> -- go forward by <n> filemarks
+               bsf <n> -- go backward by <n> filemarks
+               eod  -- go to end of data
+               rewind -- rewind back to start of data
+               eject  -- rewind, then eject the tape. 
+               erase  -- (short) erase the tape (we have no long erase)
+               mark <n> -- write <n> filemarks.
+               seek <n> -- seek to position <n>.
+
+               write <blksize> <-- write blocks from stdin to the tape 
+               read  [<blksize>] [<#blocks/#bytes>] -- read blocks from tape, write to stdout. 
+
+       See the 'tapeinfo' program for status info about the tape drive.
 
  */
 
 #include "mtx.h"
 #include "mtxl.h"
 
+#if HAVE_UNISTD_H
 #include <unistd.h>
+#endif
+
+#if HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+
+#if HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
+#endif
+
+#if HAVE_SYS_MTIO_H
 #include <sys/mtio.h> /* will try issuing some ioctls for Solaris, sigh. */
+#endif
+
+#ifdef _MSC_VER
+#include <io.h>
+#endif
 
 void Usage(void) {
   FatalError("Usage: scsitape -f <generic-device> <command> where <command> is:\n setblk <n> | fsf <n> | bsf <n> | eod | rewind | eject | mark <n> |\n  seek <n> | read [<blksize> [<numblocks]] | write [<blocksize>] \n");
@@ -54,8 +69,8 @@ void Usage(void) {
 static int arg[4];  /* the argument for the command, sigh. */
 
 /* the device handle we're operating upon, sigh. */
-static unsigned char *device;  /* the text of the device thingy. */
-static DEVICE_TYPE MediumChangerFD = (DEVICE_TYPE) 0;
+static char *device;  /* the text of the device thingy. */
+static DEVICE_TYPE MediumChangerFD = (DEVICE_TYPE) -1;
 
 
 
@@ -75,109 +90,78 @@ static int S_write(void);
 
 
 struct command_table_struct {
-  int num_args;
-  char *name;
-  int (*command)(void);
+       int num_args;
+       char *name;
+       int (*command)(void);
 } command_table[] = {
-  { 1, "setblk", S_setblk },
-  { 1, "fsf", S_fsf },
-  { 1, "bsf", S_bsf },
-  { 0, "eod", S_eod },
-  { 0, "rewind", S_rewind },
-  { 0, "eject", S_eject },
-  { 0, "reten", S_reten },
-  { 0, "erase", S_erase },
-  { 1, "mark", S_mark },
-  { 1, "seek", S_seek },
-  { 2, "read", S_read },
-  { 2, "write",S_write }
+       { 1, "setblk", S_setblk },
+       { 1, "fsf", S_fsf },
+       { 1, "bsf", S_bsf },
+       { 0, "eod", S_eod },
+       { 0, "rewind", S_rewind },
+       { 0, "eject", S_eject },
+       { 0, "reten", S_reten },
+       { 0, "erase", S_erase },
+       { 1, "mark", S_mark },
+       { 1, "seek", S_seek },
+       { 2, "read", S_read },
+       { 2, "write",S_write },
+       { 0, NULL, NULL } /* terminate list */
 };
 
 char *argv0;
 
-/* A table for printing out the peripheral device type as ASCII. */ 
-static char *PeripheralDeviceType[32] = {
-  "Disk Drive",
-  "Tape Drive",
-  "Printer",
-  "Processor",
-  "Write-once",
-  "CD-ROM",
-  "Scanner",
-  "Optical",
-  "Medium Changer",
-  "Communications",
-  "ASC IT8",
-  "ASC IT8",
-  "RAID Array",
-  "Enclosure Services",
-  "OCR/W",
-  "Bridging Expander", /* 0x10 */
-  "Reserved",  /* 0x11 */
-  "Reserved", /* 0x12 */
-  "Reserved",  /* 0x13 */
-  "Reserved",  /* 0x14 */
-  "Reserved",  /* 0x15 */
-  "Reserved",  /* 0x16 */
-  "Reserved",  /* 0x17 */
-  "Reserved",  /* 0x18 */
-  "Reserved",  /* 0x19 */
-  "Reserved",  /* 0x1a */
-  "Reserved",  /* 0x1b */
-  "Reserved",  /* 0x1c */
-  "Reserved",  /* 0x1d */
-  "Reserved",  /* 0x1e */
-  "Unknown"    /* 0x1f */
-};
-
-
 
 /* open_device() -- set the 'fh' variable.... */
-void open_device(void) {
-
-  if (MediumChangerFD) {
-    SCSI_CloseDevice("Unknown",MediumChangerFD);  /* close it, sigh...  new device now! */
-  }
-
-  MediumChangerFD = SCSI_OpenDevice(device);
+void open_device(void)
+{
+       if (MediumChangerFD != -1)
+       {
+               SCSI_CloseDevice("Unknown",MediumChangerFD);  /* close it, sigh...  new device now! */
+       }
 
+       MediumChangerFD = SCSI_OpenDevice(device);
 }
 
-static int get_arg(char *arg) {
-  int retval=-1;
+static int get_arg(char *arg)
+{
+       int retval=-1;
 
-  if (*arg < '0' || *arg > '9') {
-    return -1;  /* sorry! */
-  }
+       if (*arg < '0' || *arg > '9')
+       {
+               return -1;  /* sorry! */
+       }
 
-  retval=atoi(arg);
-  return retval;
+       retval=atoi(arg);
+       return retval;
 }
 
 
 /* we see if we've got a file open. If not, we open one :-(. Then
  * we execute the actual command. Or not :-(. 
  */ 
-int execute_command(struct command_table_struct *command) {
-
-  /* if the device is not already open, then open it from the 
-   * environment.
-   */
-  if (!MediumChangerFD) {
-    /* try to get it from STAPE or TAPE environment variable... */
-    device=getenv("STAPE");
-    if (device==NULL) {
-      device=getenv("TAPE");
-      if (device==NULL) {
-       Usage();
-      }
-    }
-    open_device();
-  }
-
-
-  /* okay, now to execute the command... */
-  return command->command();
+int execute_command(struct command_table_struct *command)
+{
+       /* if the device is not already open, then open it from the 
+       * environment.
+       */
+       if (!MediumChangerFD == -1)
+       {
+               /* try to get it from STAPE or TAPE environment variable... */
+               device = getenv("STAPE");
+               if (device == NULL)
+               {
+                       device = getenv("TAPE");
+                       if (device == NULL)
+                       {
+                               Usage();
+                       }
+               }
+               open_device();
+       }
+
+       /* okay, now to execute the command... */
+       return command->command();
 }
 
 
@@ -190,55 +174,69 @@ int execute_command(struct command_table_struct *command) {
  * in the cabinet). 
  */ 
 
-int parse_args(int argc,char **argv) {
-  int i,cmd_tbl_idx,retval,arg_idx;
-  struct command_table_struct *command;
-
-  i=1;
-  arg_idx=0;
-  while (i<argc) {
-    if (strcmp(argv[i],"-f") == 0) {
-      i++;
-      if (i>=argc) {
-       Usage();
-      }
-      device=argv[i++];
-      open_device(); /* open the device and do a status scan on it... */
-    } else {
-      cmd_tbl_idx=0;
-      command=&command_table[0]; /* default to the first command... */
-      command=&command_table[cmd_tbl_idx];
-      while (command->name) {
-       if (!strcmp(command->name,argv[i])) {
-         /* we have a match... */
-         break;
+int parse_args(int argc, char **argv)
+{
+       int i, cmd_tbl_idx,retval,arg_idx;
+       struct command_table_struct *command;
+
+       i=1;
+       arg_idx = 0;
+       while (i < argc)
+       {
+               if (strcmp(argv[i],"-f") == 0)
+               {
+                       i++;
+                       if (i >= argc)
+                       {
+                               Usage();
+                       }
+                       device = argv[i++];
+                       open_device(); /* open the device and do a status scan on it... */
+               }
+               else
+               {
+                       cmd_tbl_idx=0;
+                       command = &command_table[0]; /* default to the first command... */
+                       command = &command_table[cmd_tbl_idx];
+                       while (command->name)
+                       {
+                               if (strcmp(command->name,argv[i]) == 0)
+                               {
+                                       /* we have a match... */
+                                       break;
+                               }
+                               /* otherwise we don't have a match... */
+                               cmd_tbl_idx++;
+                               command = &command_table[cmd_tbl_idx];
+                       }
+                       /* if it's not a command, exit.... */
+                       if (command->name == NULL)
+                       {
+                               Usage();
+                       }
+                       i++;  /* go to the next argument, if possible... */
+                       /* see if we need to gather arguments, though! */
+                       arg1 = -1; /* default it to something */
+                       for (arg_idx=0;arg_idx < command->num_args ; arg_idx++)
+                       {
+                               if (i < argc)
+                               {
+                                       arg[arg_idx] = get_arg(argv[i]);
+                                       if (arg[arg_idx] !=  -1)
+                                       {
+                                               i++; /* increment i over the next cmd. */
+                                       }
+                               }
+                               else
+                               {
+                                       arg[arg_idx] = 0; /* default to 0 setmarks or whatever */
+                               }
+                       }
+                       retval=execute_command(command);  /* execute_command handles 'stuff' */
+                       exit(retval);
+               }
        }
-       /* otherwise we don't have a match... */
-       cmd_tbl_idx++;
-       command=&command_table[cmd_tbl_idx];
-      }
-      /* if it's not a command, exit.... */
-      if (!command->name) {
-       Usage();
-      }
-      i++;  /* go to the next argument, if possible... */
-      /* see if we need to gather arguments, though! */
-      arg1=-1; /* default it to something */
-      for (arg_idx=0;arg_idx < command->num_args ; arg_idx++) {
-       if (i < argc) {
-         arg[arg_idx]=get_arg(argv[i]);
-         if (arg[arg_idx] !=  -1) {
-           i++; /* increment i over the next cmd. */
-         }
-       } else {
-         arg[arg_idx]=0; /* default to 0 setmarks or whatever */
-       } 
-      }
-      retval=execute_command(command);  /* execute_command handles 'stuff' */
-      exit(retval);
-    }
-  }
-  return 0; /* should never get here */
+       return 0; /* should never get here */
 }
 
 /* For Linux, this allows us to do a short erase on a tape (sigh!).
@@ -248,21 +246,24 @@ int parse_args(int argc,char **argv) {
  * driver. Note that to do an erase, you must first rewind!
 
  */
-static int S_erase(void) {
-  int retval;
-  RequestSense_T *RequestSense;
-
-  retval=S_rewind();
-  if (retval) {
-    return retval;  /* we have an exit status :-(. */
-  } 
-
-  RequestSense=Erase(MediumChangerFD);
-  if (RequestSense) {
-    PrintRequestSense(RequestSense);
-    exit(1);  /* exit with an error status. */
-  }
-  return 0;
+static int S_erase(void)
+{
+       int retval;
+       RequestSense_T *RequestSense;
+
+       retval=S_rewind();
+       if (retval)
+       {
+               return retval;  /* we have an exit status :-(. */
+       } 
+
+       RequestSense=Erase(MediumChangerFD);
+       if (RequestSense)
+       {
+               PrintRequestSense(RequestSense);
+               exit(1);  /* exit with an error status. */
+       }
+       return 0;
 }
 
 /* This should eject a tape or magazine, depending upon the device sent
@@ -270,91 +271,97 @@ static int S_erase(void) {
  */
 static int S_eject(void)
 {
-int i;
-  i=Eject(MediumChangerFD);
-  if (i<0) {
-    fprintf(stderr,"scsitape:eject failed\n");
-    fflush(stderr);
-  }
-  return i;  /* if it failed, well, sigh.... */
+       int i;
+       i = LoadUnload(MediumChangerFD, 0);
+       if ( i < 0)
+       {
+               fprintf(stderr,"scsitape:eject failed\n");
+               fflush(stderr);
+       }
+       return i;
 }
 
 
 
-
 /* We write a filemarks of 0 before going to grab position, in order
  * to insure that data in the buffer is not a problem. 
  */
 
-static int S_mark(void) {
-  RequestSense_T RequestSense; /* for result of ReadElementStatus */
-  CDB_T CDB;
-  unsigned char buffer[6];
-  int count=arg1; /* voila! */
-
-  CDB[0]=0x10;  /* SET_MARK */
-  CDB[1]=0;
-  CDB[2]=(count >> 16) & 0xff;
-  CDB[3]=(count >>8) & 0xff;
-  CDB[4]=count & 0xff;
-  CDB[5]=0; 
-
-  /* we really don't care if this command works or not, sigh.  */
-  slow_bzero((unsigned char *)&RequestSense,sizeof(RequestSense_T));
-  if (SCSI_ExecuteCommand(MediumChangerFD,Input,&CDB,6,buffer,0,&RequestSense)!=0){
-    PrintRequestSense(&RequestSense);
-    return 1;
-  }
-  return 0;
+static int S_mark(void)
+{
+       RequestSense_T RequestSense; /* for result of ReadElementStatus */
+       CDB_T CDB;
+       unsigned char buffer[6];
+       int count = arg1; /* voila! */
+
+       CDB[0] = 0x10;  /* SET_MARK */
+       CDB[1] = 0;
+       CDB[2] = (unsigned char)(count >> 16);
+       CDB[3] = (unsigned char)(count >> 8);
+       CDB[4] = (unsigned char)count;
+       CDB[5] = 0; 
+
+       /* we really don't care if this command works or not, sigh.  */
+       slow_bzero((char *)&RequestSense, sizeof(RequestSense_T));
+
+       if (SCSI_ExecuteCommand(MediumChangerFD, Input, &CDB, 6, buffer, 0, &RequestSense)!= 0)
+       {
+               PrintRequestSense(&RequestSense);
+               return 1;
+       }
+       return 0;
 }
 /* let's rewind to bod! 
  */
 
-static int S_rewind(void) {
-  RequestSense_T sense;
-  CDB_T CDB;
-  unsigned char buffer[6];
-
-  CDB[0]=0x01;  /* REWIND */
-  CDB[1]=0;
-  CDB[2]=0;
-  CDB[3]=0;
-  CDB[4]=0;
-  CDB[5]=0; 
-
-  /* we really don't care if this command works or not, sigh.  */
-  slow_bzero((unsigned char *)&sense,sizeof(RequestSense_T));
-  if (SCSI_ExecuteCommand(MediumChangerFD,Input,&CDB,6,buffer,0,&sense)!=0){
-    PrintRequestSense(&sense);
-    return 1;
-  }
-  return 0;
+static int S_rewind(void)
+{
+       RequestSense_T sense;
+       CDB_T CDB;
+       unsigned char buffer[6];
+
+       CDB[0] = 0x01;  /* REWIND */
+       CDB[1] = 0;
+       CDB[2] = 0;
+       CDB[3] = 0;
+       CDB[4] = 0;
+       CDB[5] = 0; 
+
+       /* we really don't care if this command works or not, sigh.  */
+       slow_bzero((char *)&sense,sizeof(RequestSense_T));
+       if (SCSI_ExecuteCommand(MediumChangerFD,Input,&CDB,6,buffer,0,&sense)!=0)
+       {
+               PrintRequestSense(&sense);
+               return 1;
+       }
+       return 0;
 }
 
 
 
 
 /* This is used for fsf and bsf. */
-static int Space(int count,int code){
-  RequestSense_T sense;
-  CDB_T CDB;
-  unsigned char buffer[6];
-
-  CDB[0]=0x11;  /* SET_MARK */
-  CDB[1]=code;
-  CDB[2]=(count >> 16) & 0xff;
-  CDB[3]=(count >>8) & 0xff;
-  CDB[4]=count & 0xff;
-  CDB[5]=0; 
-
-  /* we really don't care if this command works or not, sigh.  */
-  slow_bzero((unsigned char *)&sense,sizeof(RequestSense_T));
-  if (SCSI_ExecuteCommand(MediumChangerFD,Input,&CDB,6,buffer,0,&sense)!=0){
-    PrintRequestSense(&sense);
-    return 1;
-  }
-  return 0;
-  
+static int Space(int count, char code)
+{
+       RequestSense_T sense;
+       CDB_T CDB;
+       unsigned char buffer[6];
+
+       CDB[0] = 0x11;  /* SET_MARK */
+       CDB[1] = code;
+       CDB[2] = (unsigned char)(count >> 16);
+       CDB[3] = (unsigned char)(count >> 8);
+       CDB[4] = (unsigned char)count;
+       CDB[5] = 0; 
+
+       /* we really don't care if this command works or not, sigh.  */
+       slow_bzero((char *)&sense,sizeof(RequestSense_T));
+       if (SCSI_ExecuteCommand(MediumChangerFD, Input, &CDB, 6, buffer, 0, &sense) != 0)
+       {
+               PrintRequestSense(&sense);
+               return 1;
+       }
+       return 0;
 }
 
 
@@ -363,141 +370,150 @@ static int Space(int count,int code){
  * to insure that data in the buffer is not a problem. 
  */
 
-static int S_fsf(void) {
-  return Space(arg1,1); /* go forward! */
+static int S_fsf(void)
+{
+       return Space(arg1,1); /* go forward! */
 }
 
-static int S_bsf(void) {
-  return Space(-arg1,1); /* go backward! */
+static int S_bsf(void)
+{
+       return Space(-arg1,1); /* go backward! */
 }
 
-static int S_eod(void) {
-  return Space(0,3); /* go to eod! */
+static int S_eod(void)
+{
+       return Space(0,3); /* go to eod! */
 }
 
 /* sigh, abuse of the LOAD command...
 
  */
-static int S_reten(void) {
-  RequestSense_T sense;
-  CDB_T CDB;
-  unsigned char buffer[6];
-
-  CDB[0]=0x1b;  /* START_STOP */
-  CDB[1]=0; /* wait */
-  CDB[2]=0;
-  CDB[3]=0;
-  CDB[4]=3; /* reten. */ 
-  CDB[5]=0; 
-
-  /* we really don't care if this command works or not, sigh.  */
-  slow_bzero((unsigned char *)&sense,sizeof(RequestSense_T));
-  if (SCSI_ExecuteCommand(MediumChangerFD,Input,&CDB,6,buffer,0,&sense)!=0){
-    PrintRequestSense(&sense);
-    return 1;
-  }
-  return 0;
-
+static int S_reten(void)
+{
+       RequestSense_T sense;
+       CDB_T CDB;
+       unsigned char buffer[6];
+
+       CDB[0] = 0x1B;  /* START_STOP */
+       CDB[1] = 0; /* wait */
+       CDB[2] = 0;
+       CDB[3] = 0;
+       CDB[4] = 3; /* reten. */ 
+       CDB[5] = 0; 
+
+       /* we really don't care if this command works or not, sigh.  */
+       slow_bzero((char *)&sense, sizeof(RequestSense_T));
+       if (SCSI_ExecuteCommand(MediumChangerFD, Input, &CDB, 6, buffer, 0, &sense) != 0)
+       {
+               PrintRequestSense(&sense);
+               return 1;
+       }
+       return 0;
 }
 
 /* seek a position on the tape (sigh!) */
-static int S_seek(void){
-  RequestSense_T sense;
-  CDB_T CDB;
-  unsigned char buffer[6];
-  int count =  arg1;
-
-  /* printf("count=%d\n",arg1); */
-
-  CDB[0]=0x2b;  /* LOCATE */
-  CDB[1]=0;  /* Logical */
-  CDB[2]=0; /* padding */
-  CDB[3]=(count >> 24) & 0xff;
-  CDB[4]=(count >> 16) & 0xff;
-  CDB[5]=(count >>8) & 0xff;
-  CDB[6]=count & 0xff;
-  CDB[7]=0; 
-  CDB[8]=0; 
-  CDB[9]=0; 
-
-  /* we really don't care if this command works or not, sigh.  */
-  slow_bzero((unsigned char *)&sense,sizeof(RequestSense_T));
-  if (SCSI_ExecuteCommand(MediumChangerFD,Input,&CDB,10,buffer,0,&sense)!=0){
-    PrintRequestSense(&sense);
-    return 1;
-  }
-  return 0;
+static int S_seek(void)
+{
+       RequestSense_T sense;
+       CDB_T CDB;
+       unsigned char buffer[6];
+       int count =  arg1;
+
+       /* printf("count=%d\n",arg1); */
+
+       CDB[0] = 0x2B;  /* LOCATE */
+       CDB[1] = 0;  /* Logical */
+       CDB[2] = 0; /* padding */
+       CDB[3] = (unsigned char)(count >> 24);
+       CDB[4] = (unsigned char)(count >> 16);
+       CDB[5] = (unsigned char)(count >> 8);
+       CDB[6] = (unsigned char)count;
+       CDB[7] = 0; 
+       CDB[8] = 0; 
+       CDB[9] = 0; 
+
+       /* we really don't care if this command works or not, sigh.  */
+       slow_bzero((char *)&sense,sizeof(RequestSense_T));
+       if (SCSI_ExecuteCommand(MediumChangerFD, Input, &CDB, 10, buffer, 0, &sense) != 0)
+       {
+               PrintRequestSense(&sense);
+               return 1;
+       }
+       return 0;
 }
 
 #ifdef MTSRSZ
-static int Solaris_setblk(int fh,int count) {
-  /* we get here only if we have a MTSRSZ, which means Solaris. */
-  struct mtop mt_com;  /* the struct used for the MTIOCTOP ioctl */
-  int result;
-
-  /* okay, we have fh and count.... */
-  
-  /* Now to try the ioctl: */
-  mt_com.mt_op=MTSRSZ;
-  mt_com.mt_count=count;
-
-  /* surround the actual ioctl to enable threading, since fsf/etc. can be
-   * big time consumers and we want other threads to be able to run too. 
-   */
-  result=ioctl(fh, MTIOCTOP, (char *)&mt_com);
-
-  if (result < 0) {
-    return errno;
-  }
-
-  /* okay, we did okay. Return a value of None... */
-  return 0;
+static int Solaris_setblk(int fh,int count)
+{
+       /* we get here only if we have a MTSRSZ, which means Solaris. */
+       struct mtop mt_com;  /* the struct used for the MTIOCTOP ioctl */
+       int result;
+
+       /* okay, we have fh and count.... */
+
+       /* Now to try the ioctl: */
+       mt_com.mt_op=MTSRSZ;
+       mt_com.mt_count=count;
+
+       /* surround the actual ioctl to enable threading, since fsf/etc. can be
+        * big time consumers and we want other threads to be able to run too. 
+        */
+
+       result=ioctl(fh, MTIOCTOP, (char *)&mt_com);
+
+       if (result < 0)
+       {
+               return errno;
+       }
+
+       /* okay, we did okay. Return a value of None... */
+       return 0;
 }
-#endif  
+#endif
 
 
 /* okay, this is a write: we need to set the block size to something: */
-static int S_setblk(void) {
-  RequestSense_T sense;
-  CDB_T CDB;
-  unsigned char buffer[12];
-  unsigned int count = (unsigned int) arg1;
-
-  
-  CDB[0]=0x15;  /* MODE SELECT */
-  CDB[1]=0x10;  /* scsi2 */
-  CDB[2]=0; 
-  CDB[3]=0;
-  CDB[4]=12; /* length of data */
-  CDB[5]=0;
-
-  slow_bzero((unsigned char *)&sense,sizeof(RequestSense_T));
-  slow_bzero(buffer,12);
-
-  /* Now to set the mode page header: */
-  buffer[0]=0;
-  buffer[1]=0;
-  buffer[2]=0x10; /* we are in buffered mode now, people! */
-  buffer[3]=8; /* block descriptor length. */ 
-  buffer[4]=0; /* reset to default density, sigh. */ /* 0 */
-  buffer[5]=0; /* 1 */
-  buffer[6]=0; /* 2 */
-  buffer[7]=0; /* 3 */
-  buffer[8]=0; /* 4 */
-  buffer[9]=(count >> 16) & 0xff; /* 5 */
-  buffer[10]=(count >> 8) & 0xff; /* 6 */
-  buffer[11]= count & 0xff;  /* 7 */
-     
-  if (SCSI_ExecuteCommand(MediumChangerFD,Output,&CDB,6,buffer,12,&sense)!=0){
-    PrintRequestSense(&sense);
-    return 1;
-  }
+static int S_setblk(void)
+{
+       RequestSense_T sense;
+       CDB_T CDB;
+       char buffer[12];
+       unsigned int count = (unsigned int) arg1;
+
+       CDB[0] = 0x15;  /* MODE SELECT */
+       CDB[1] = 0x10;  /* scsi2 */
+       CDB[2] = 0; 
+       CDB[3] = 0;
+       CDB[4] = 12; /* length of data */
+       CDB[5] = 0;
+
+       slow_bzero((char *)&sense, sizeof(RequestSense_T));
+       slow_bzero(buffer, 12);
+
+       /* Now to set the mode page header: */
+       buffer[0] = 0;
+       buffer[1] = 0;
+       buffer[2] = 0x10; /* we are in buffered mode now, people! */
+       buffer[3] = 8; /* block descriptor length. */ 
+       buffer[4] = 0; /* reset to default density, sigh. */ /* 0 */
+       buffer[5] = 0; /* 1 */
+       buffer[6] = 0; /* 2 */
+       buffer[7] = 0; /* 3 */
+       buffer[8] = 0; /* 4 */
+       buffer[9] = (unsigned char)(count >> 16); /* 5 */
+       buffer[10] = (unsigned char)(count >> 8); /* 6 */
+       buffer[11] = (unsigned char)count;  /* 7 */
+
+       if (SCSI_ExecuteCommand(MediumChangerFD,Output,&CDB,6,buffer,12,&sense)!=0)
+       {
+               PrintRequestSense(&sense);
+               return 1;
+       }
 #ifdef MTSRSZ
-  /*   Solaris_setblk(MediumChangerFD,count);   */
+       /*   Solaris_setblk(MediumChangerFD,count);   */
 #endif
 
-  return 0;
+       return 0;
 }
 
 /*************************************************************************/
@@ -541,7 +557,7 @@ static int S_setblk(void) {
  * detect a short read while in variable block mode. We'll see.
  */
 #define SHORT_READ(s) (S_NO_SENSE((s)) && (s).ILI && (s).Valid &&  (s).AdditionalSenseCode==0  && (s).AdditionalSenseCodeQualifier==0)
-                      
+
 #define HIT_EOD(s) (S_BLANK_CHECK((s)) && (s).Valid)
 #define HIT_EOP(s) (S_MEDIUM_ERROR((s)) && (s).EOM && (s).Valid)
 #define HIT_EOM(s) ((s).EOM && (s).Valid)
@@ -553,196 +569,247 @@ static int S_setblk(void) {
  * we are in trouble anyhow. 
  */
 int SCSI_readt(DEVICE_TYPE fd, char * buf, unsigned int bufsize, unsigned int *len, unsigned int timeout) {
-  int rtnval;
-  CDB_T cmd;
-
-  int blockCount;
-  int info;
-  
-  RequestSense_T RequestSense;
-  
-  if (bufsize==0) { /* we are in variable block mode */
-    blockCount=MAX_READ_SIZE; /* variable block size. */
-  } else {
-    blockCount= *len / bufsize ;
-    if ((*len % bufsize) != 0) {
-      fprintf(stderr,"Error: Data (%d bytes) not even multiple of block size (%d bytes).\n",*len,bufsize);
-      exit(1); /* we're finished, sigh. */
-    }
-  }
-  
-  if (timeout == 0) {
-    timeout = 1 * 60; /* 1 minutes */
-  }
-  
-  memset(&cmd, 0, sizeof(CDB_T));
-  cmd[0] = 0x08; /* READ */
-  cmd[1] = (bufsize) ? 1 : 0; /* fixed length or var length blocks */
-  cmd[2] = (blockCount >> 16) & 0xff; /* MSB */
-  cmd[3] = (blockCount >> 8) & 0xff;
-  cmd[4] = blockCount & 0xff; /* LSB */
-  
-  /* okay, let's read, look @ the result code: */
-  rtnval=READ_OK;
-  if (SCSI_ExecuteCommand(fd,Input,&cmd,6,buf,(bufsize) ? *len : MAX_READ_SIZE,&RequestSense)) {
-    
-    rtnval=READ_ERROR;
-    if (HIT_EOP(RequestSense)) {
-      cmd[0]=0x08;
-      rtnval=READ_EOP;
-    }
-
-    if (HIT_FILEMARK(RequestSense)) {
-      rtnval=READ_FILEMARK;
-    }
-    if (HIT_EOD(RequestSense)) {
-      rtnval=READ_EOD;
-    }
-    if ( (bufsize==0) && SHORT_READ(RequestSense)) {
-      rtnval=READ_SHORT; /* we only do short reads for variable block mode */
-    }
-    if (rtnval != READ_ERROR) {
-      /* info contains number of blocks or bytes *not* read. May be 
-       negative if the block we were trying to read was too big. So
-       we will have to account for that and set it to zero if so, so that
-       we return the proper # of blocks read. 
-      */
-      info=((RequestSense.Information[0]<<24) +
-           (RequestSense.Information[1]<<16) +
-           (RequestSense.Information[2]<<8) +
-           RequestSense.Information[3]);
-      /* on 64-bit platforms, we may need to turn 'info' into a negative # */
-      if (info > 0x7fffffff) info = 0;
-      if (info < 0) info=0;  /* make sure  we don't return too big len read. */
-      /* Now set *len to # of bytes read. */
-      *len= bufsize ? (blockCount-info) * bufsize : MAX_READ_SIZE-info ;
-    } else {
-      PrintRequestSense(&RequestSense);
-      exit(1);  /* foo. */
-    }
-  }
-  
-  return(rtnval);
+       int rtnval;
+       CDB_T cmd;
+
+       int blockCount;
+       int info;
+
+       RequestSense_T RequestSense;
+
+       if (bufsize==0)
+       {
+               /* we are in variable block mode */
+               blockCount=MAX_READ_SIZE; /* variable block size. */
+       }
+       else
+       {
+               blockCount= *len / bufsize;
+               if ((*len % bufsize) != 0)
+               {
+                       fprintf(stderr,"Error: Data (%d bytes) not even multiple of block size (%d bytes).\n",*len,bufsize);
+                       exit(1); /* we're finished, sigh. */
+               }
+       }
+
+       if (timeout == 0)
+       {
+               timeout = 1 * 60; /* 1 minutes */
+       }
+
+       memset(&cmd, 0, sizeof(CDB_T));
+       cmd[0] = 0x08; /* READ */
+       cmd[1] = (bufsize) ? 1 : 0; /* fixed length or var length blocks */
+       cmd[2] = (unsigned char)(blockCount >> 16); /* MSB */
+       cmd[3] = (unsigned char)(blockCount >> 8);
+       cmd[4] = (unsigned char)blockCount; /* LSB */
+
+       /* okay, let's read, look @ the result code: */
+       rtnval=READ_OK;
+       if (SCSI_ExecuteCommand(fd,Input,&cmd,6,buf,(bufsize) ? *len : MAX_READ_SIZE,&RequestSense))
+       {
+               rtnval=READ_ERROR;
+               if (HIT_EOP(RequestSense))
+               {
+                       cmd[0]=0x08;
+                       rtnval=READ_EOP;
+               }
+
+               if (HIT_FILEMARK(RequestSense))
+               {
+                       rtnval=READ_FILEMARK;
+               }
+
+               if (HIT_EOD(RequestSense))
+               {
+                       rtnval=READ_EOD;
+               }
+
+               if ( (bufsize==0) && SHORT_READ(RequestSense))
+               {
+                       rtnval=READ_SHORT; /* we only do short reads for variable block mode */
+               }
+
+               if (rtnval != READ_ERROR)
+               {
+                       /* info contains number of blocks or bytes *not* read. May be 
+                       negative if the block we were trying to read was too big. So
+                       we will have to account for that and set it to zero if so, so that
+                       we return the proper # of blocks read. 
+                       */
+                       info = ((RequestSense.Information[0] << 24) +
+                                       (RequestSense.Information[1] << 16) +
+                                       (RequestSense.Information[2] << 8) +
+                                        RequestSense.Information[3]);
+
+                       /* on 64-bit platforms, we may need to turn 'info' into a negative # */
+                       if (info > 0x7fffffff)
+                               info = 0;
+
+                       if (info < 0)
+                               info=0;  /* make sure  we don't return too big len read. */
+
+                       /* Now set *len to # of bytes read. */
+                       *len= bufsize ? (blockCount-info) * bufsize : MAX_READ_SIZE-info ;
+               }
+               else
+               {
+                       PrintRequestSense(&RequestSense);
+                       exit(1);  /* foo. */
+               }
+       }
+
+       return rtnval;
 }
 
 /* Low level SCSI write. Modified from BRU 16.1,  with much BRU smarts
  * taken out and with the various types changed to mtx types rather than
  * BRU types.
  */ 
-int SCSI_writet(DEVICE_TYPE fd, char * buf, unsigned int blocksize,
-                unsigned int *len, 
-               unsigned int timeout) {
-  CDB_T cmd;
-
-  int blockCount;
-  int rtnval=0;
-  RequestSense_T RequestSense;
-
-  if (blocksize==0) { /* we are in variable block mode */
-    blockCount=*len; /* variable block size. */
-  } else {
-    blockCount= *len / blocksize ;
-    if ((*len % blocksize) != 0) {
-      fprintf(stderr,"Error: Data (%d bytes) not even multiple of block size (%d bytes).\n",*len,blocksize);
-      exit(1); /* we're finished, sigh. */
-    }
-  }
-
-  fprintf(stderr,"Writing %d blocks\n",blockCount);
-  
-  memset(&cmd, 0, sizeof(CDB_T));
-  cmd[0] = 0x0a; /* WRITE */
-  cmd[1] = (blocksize) ? 1 : 0; /* fixed length or var length blocks */
-  cmd[2] = (blockCount >> 16) & 0xff; /* MSB */
-  cmd[3] = (blockCount >> 8) & 0xff;
-  cmd[4] = blockCount & 0xff; /* LSB */
-  
-  
-  if (SCSI_ExecuteCommand(fd,Output,&cmd,6,buf, *len, &RequestSense)) {
-    if (HIT_EOM(RequestSense)) {
-      /* we hit end of media. Return -1. */
-      if (S_VOLUME_OVERFLOW(RequestSense)) {
-       exit(WRITE_EOV);
-      }
-      exit(WRITE_EOM); /* end of media! */
-    }
-    else { /* it was plain old write error: */
-      PrintRequestSense(&RequestSense);
-      exit(WRITE_ERROR);
-    }
-  } else {
-    rtnval = *len; /* worked! */
-  }
-  return(rtnval);
+int SCSI_write(DEVICE_TYPE fd, char * buf, unsigned int blocksize,
+                               unsigned int *len)
+{
+       CDB_T cmd;
+
+       int blockCount;
+       int rtnval=0;
+       RequestSense_T RequestSense;
+
+       if (blocksize == 0)
+       {
+               /* we are in variable block mode */
+               blockCount = *len; /* variable block size. */
+       }
+       else
+       {
+               blockCount= *len / blocksize ;
+               if ((*len % blocksize) != 0)
+               {
+                       fprintf(stderr,"Error: Data (%d bytes) not even multiple of block size (%d bytes).\n",*len,blocksize);
+                       exit(1); /* we're finished, sigh. */
+               }
+       }
+
+       fprintf(stderr,"Writing %d blocks\n",blockCount);
+
+       memset(&cmd, 0, sizeof(CDB_T));
+       cmd[0] = 0x0a; /* WRITE */
+       cmd[1] = (blocksize) ? 1 : 0; /* fixed length or var length blocks */
+       cmd[2] = (unsigned char)(blockCount >> 16); /* MSB */
+       cmd[3] = (unsigned char)(blockCount >> 8);
+       cmd[4] = (unsigned char)blockCount; /* LSB */
+
+
+       if (SCSI_ExecuteCommand(fd,Output,&cmd,6,buf, *len, &RequestSense))
+       {
+               if (HIT_EOM(RequestSense))
+               {
+                       /* we hit end of media. Return -1. */
+                       if (S_VOLUME_OVERFLOW(RequestSense))
+                       {
+                               exit(WRITE_EOV);
+                       }
+                       exit(WRITE_EOM); /* end of media! */
+               }
+               else
+               {
+                       /* it was plain old write error: */
+                       PrintRequestSense(&RequestSense);
+                       exit(WRITE_ERROR);
+               }
+       }
+       else
+       {
+               rtnval = *len; /* worked! */
+       }
+       return rtnval;
 }
 
 /* S_write is not implemented yet! */
-static int S_write(void) {
-  unsigned char *buffer; /* the buffer we're gonna read/write out of. */
-  int buffersize;
-  int len; /* the length of the data in the buffer */
-  int blocksize=arg[0];
-  int numblocks=arg[1];
-  int varsize=0; /* variable size block flag */
-  int result;
-  int eof_input;
-  int infile=fileno(stdin); /* sigh */
-
-  if (blocksize==0) {
-    varsize=1;
-    buffersize=MAX_READ_SIZE;
-    len=MAX_READ_SIZE;
-  }  else {
-    varsize=0; /* fixed block mode */
-    buffersize=blocksize;
-    len=blocksize;
-  }
-  /* sigh, make it oversized just to have some */  
-  buffer=malloc(buffersize+8); 
-
-  eof_input=0;
-  while (!eof_input) {
-    /* size_t could be 64 bit on a 32 bit platform, so do casts. */
-    len=0;
-    /* If it is a pipe, we could read 4096 bytes rather than the full
-     * 128K bytes or whatever, so we must gather multiple reads into
-     * the buffer.
-     */
-    while (len < buffersize) {
-      result=(int)read(infile,buffer+len,(size_t)(buffersize-len));
-      if (!result) {
-       eof_input=1;
-       if (!len) { /* if we have no deata in our buffer, exit */
-         return 0; /* we're at end of file! */
+static int S_write(void)
+{
+       char *buffer; /* the buffer we're gonna read/write out of. */
+       int buffersize;
+       int len; /* the length of the data in the buffer */
+       int blocksize = arg[0];
+       int numblocks = arg[1];
+       int varsize=0; /* variable size block flag */
+       int result;
+       int eof_input;
+       int infile=fileno(stdin); /* sigh */
+
+       if (blocksize == 0)
+       {
+               varsize = 1;
+               buffersize = MAX_READ_SIZE;
+               len = MAX_READ_SIZE;
        }
-       break; /* otherwise, break and write the data */
-      }
-      len+=result;  /* add the result input to our length. */
-    }
-    
-
-    result=SCSI_writet(MediumChangerFD,buffer,blocksize,&len,DEFAULT_TIMEOUT);
-    if (!result) {
-      return 1; /* at end of tape! */
-    }
-    /* Now see if we have numbytes or numblocks. If so, we may wish to exit
-       this loop.
-    */
-    if (arg[1]) {
-      if (varsize) {
-       /***BUG***/
-       return 0; /* we will only write one block in variable size mode :-( */
-      } else {
-       if (numblocks) {
-         numblocks--;
-       } else {
-         return 0; /* we're done. */
+       else
+       {
+               varsize = 0; /* fixed block mode */
+               buffersize = blocksize;
+               len = blocksize;
        }
-      }
-    }
-  }
-  /* and done! */
-  return 0;
+
+       /* sigh, make it oversized just to have some */  
+       buffer = malloc(buffersize+8); 
+
+       eof_input = 0;
+       while (!eof_input)
+       {
+               /* size_t could be 64 bit on a 32 bit platform, so do casts. */
+               len=0;
+               /* If it is a pipe, we could read 4096 bytes rather than the full
+               * 128K bytes or whatever, so we must gather multiple reads into
+               * the buffer.
+               */
+               while (len < buffersize)
+               {
+                       result=(int)read(infile, buffer + len, (size_t)(buffersize - len));
+                       if (!result)
+                       {
+                               eof_input = 1;
+                               if (!len)
+                               {
+                                       /* if we have no deata in our buffer, exit */
+                                       return 0; /* we're at end of file! */
+                               }
+                               break;          /* otherwise, break and write the data */
+                       }
+                       len += result;  /* add the result input to our length. */
+               }
+
+               result = SCSI_write(MediumChangerFD, buffer, blocksize, (unsigned int *)&len);
+               if (!result)
+               {
+                       return 1; /* at end of tape! */
+               }
+
+               /* Now see if we have numbytes or numblocks. If so, we may wish to exit
+               this loop.
+               */
+               if (arg[1])
+               {
+                       if (varsize)
+                       {
+                               /***BUG***/
+                               return 0; /* we will only write one block in variable size mode :-( */
+                       }
+                       else
+                       {
+                               if (numblocks)
+                               {
+                                       numblocks--;
+                               }
+                               else
+                               {
+                                       return 0; /* we're done. */
+                               }
+                       }
+               }
+       }
+       /* and done! */
+       return 0;
 }
 
 /* Okay, the read thingy: */
@@ -753,99 +820,121 @@ static int S_write(void) {
  */ 
 
 
-static int S_read(void) {
-  unsigned char *buffer; /* the buffer we're going to be reading out of */
-  int buffersize;
-  int len; /* the length of the data in the buffer */
-  int blocksize=arg[0];
-  int numblocks=arg[1];
-  int varsize=0; /* variable size block flag. */
-
-  int result;
-
-  int outfile=fileno(stdout); /* sigh. */
-  
-
-  if (blocksize==0) {
-    varsize=1;
-    buffersize=MAX_READ_SIZE;
-    len=MAX_READ_SIZE;
-  }  else {
-    varsize=0; /* fixed block mode */
-    buffersize=blocksize;
-    len=blocksize;
-  }
-  /* sigh, make it oversized just to have some */  
-  buffer=malloc(buffersize+8); 
-  
-
-  while (1) {
-    if (varsize) {
-      /* it could have gotten reset by prior short read... */
-      len=MAX_READ_SIZE; 
-    }
-    result=SCSI_readt(MediumChangerFD,buffer,blocksize, &len, DEFAULT_TIMEOUT);
-    if (result==READ_FILEMARK || result==READ_EOD || result==READ_EOP) {
-      /* okay, normal end of file? */
-      if (len > 0) {
-       write(outfile,buffer,len);
-      }
-#ifdef NEED_TO_GO_PAST_FILEMARK
-      /* Now, let's try to go past the filemark if that's what we hit: */
-      if (result==READ_FILEMARK) {
-       arg1=1; /* arg for S_fsf. */
-       S_fsf(); /* and go forward 1 filemark, we hope! */
-      }
-#endif   
-      return 0; /* hit normal end of file. */
-    } else if (result==READ_SHORT) {
-      /* short reads are only valid in variable block mode. */
-      if (varsize) {
-       if (len > 0) {
-         write(outfile,buffer,len);
+static int S_read(void)
+{
+       char *buffer; /* the buffer we're going to be reading out of */
+       int buffersize;
+       unsigned int len; /* the length of the data in the buffer */
+       int blocksize = arg[0];
+       int numblocks = arg[1];
+       int varsize = 0; /* variable size block flag. */
+
+       int result;
+
+       int outfile=fileno(stdout); /* sigh. */
+
+       if (blocksize == 0)
+       {
+               varsize=1;
+               buffersize=MAX_READ_SIZE;
+               len=MAX_READ_SIZE;
        }
-      } else {
-       fprintf(stderr,"scsitape:Short Read encountered on input. Aborting.\n");
-       fflush(stderr);
-       exit(1); /* error exit! */
-      }
-    } else if (result==READ_OK) {
-      write(outfile,buffer,len);
-    } else {
-
-      fprintf(stderr,"scsitape:Read Error\n");
-      fflush(stderr);
-      exit(1);
-    }
-    /* Now see if we have numbytes or numblocks: if so, we may wish to
-     * exit this loop.
-     */
-    if (arg[1]) {
-      if (varsize) {
-       /****BUG****/ 
-       return 0; /* we're only reading one block in var size mode! */
-      } else {
-       if (numblocks) {
-         numblocks--;
-       } else {
-         return 0; /* we're done. */
+       else
+       {
+               varsize=0; /* fixed block mode */
+               buffersize=blocksize;
+               len=blocksize;
+       }
+
+       /* sigh, make it oversized just to have some */  
+       buffer = malloc(buffersize + 8); 
+
+       for ( ; ; )
+       {
+               if (varsize)
+               {
+                       /* it could have gotten reset by prior short read... */
+                       len=MAX_READ_SIZE; 
+               }
+               result=SCSI_readt(MediumChangerFD,buffer,blocksize, &len, DEFAULT_TIMEOUT);
+
+               if (result==READ_FILEMARK || result==READ_EOD || result==READ_EOP)
+               {
+                       /* okay, normal end of file? */
+                       if (len > 0)
+                       {
+                               write(outfile,buffer,len);
+                       }
+
+#ifdef NEED_TO_GO_PAST_FILEMARK
+                       /* Now, let's try to go past the filemark if that's what we hit: */
+                       if (result==READ_FILEMARK)
+                       {
+                               arg1 = 1;       /* arg for S_fsf. */
+                               S_fsf();        /* and go forward 1 filemark, we hope! */
+                       }
+#endif
+                       return 0; /* hit normal end of file. */
+               }
+               else if (result == READ_SHORT)
+               {
+                       /* short reads are only valid in variable block mode. */
+                       if (varsize)
+                       {
+                               if (len > 0)
+                               {
+                                       write(outfile,buffer,len);
+                               }
+                       }
+                       else
+                       {
+                               fprintf(stderr,"scsitape:Short Read encountered on input. Aborting.\n");
+                               fflush(stderr);
+                               exit(1); /* error exit! */
+                       }
+               }
+               else if (result == READ_OK)
+               {
+                       write(outfile,buffer,len);
+               }
+               else
+               {
+                       fprintf(stderr,"scsitape:Read Error\n");
+                       fflush(stderr);
+                       exit(1);
+               }
+
+               /* Now see if we have numbytes or numblocks: if so, we may wish to
+                * exit this loop.
+                */
+               if (arg[1])
+               {
+                       if (varsize)
+                       {
+                               /****BUG****/ 
+                               return 0; /* we're only reading one block in var size mode! */
+                       }
+                       else if (numblocks)
+                       {
+                               numblocks--;
+                       }
+                       else
+                       {
+                               return 0; /* we're done. */
+                       }
+               }
        }
-      }
-    }
-  }
-} /* got the goddam cancer of the curly braces. You can tell I used to 
-   * do Lisp.
-   */
+}
 
 
 /* See parse_args for the scoop. parse_args does all. */
-int main(int argc, char **argv) {
-  argv0=argv[0];
-  parse_args(argc,argv);
+int main(int argc, char **argv)
+{
+       argv0 = argv[0];
+       parse_args(argc, argv);
 
-  if (device) 
-    SCSI_CloseDevice(device,MediumChangerFD);
+       if (device)
+               SCSI_CloseDevice(device,MediumChangerFD);
 
-  exit(0);
+       exit(0);
 }
-