Logo Search packages:      
Sourcecode: jazip version File versions  Download package

scsi.c

/*
 * jaZip for Linux  (c) 1996  Jarrod A. Smith
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 *
 * Part of this file is essentially Grant R. Guenther's ziptool for linux 
 * (c) 1996   Grant R. Guenther,  based on work of Itai Nahshon
 * ziptool lives at http://www.torque.net/ziptool.html
 */

/*
      This code uses SCSI_IOCTL_SEND_COMMAND to deliver vendor specific 
   commands to an Iomega ZIP drive.  The program attempts to ensure that
   the SCSI device is actually a ZIP drive and that it is not currently
   mounted.  The checks are *not* foolproof

   This code contains a password protected mode which is not (yet) supported

   Whenever you change the write-protection mode, ziptool ejects the disk.
   This is done to ensure that Linux will recheck the mode before it attempts
   to use the disk again.

*/

#include <stdio.h>
#include <mntent.h>
#include <forms.h>
#include <unistd.h>
#include "jazip.h"

#define SCSI_IOCTL_SEND_COMMAND 1

struct sdata {
      int  inlen;
      int  outlen;
      char cmd[256];
} scsi_cmd;

extern int  ioctl();
int is_mounted( char * fs )

/* -1 = error,  0 = not mounted,  1 = mounted */

{  struct mntent *mp;
   FILE *mtab;
   
   mtab = setmntent(MOUNTED,"r");
   if (!mtab) {
            sprintf (mesg, "unable to access %s", MOUNTED);
            return -1;
      }
   while ((mp=getmntent(mtab))) 
      if (!strncmp(mp->mnt_fsname,fs,8)) break;
      if( mp != NULL ){
            strcpy( mnt_fsname, mp->mnt_fsname );
            strcpy( mnt_dir, mp->mnt_dir );
            strcpy( mnt_type, mp->mnt_type );
            strcpy (mesg, "device is mounted");
      }
   endmntent(mtab);
   return (mp != NULL);
}

int is_raw_scsi( char * fs )

{     return ((strlen(fs) == 8) && (strncmp("/dev/sd",fs,7) == 0));
}

int   is_jazip( int fd )

{     char  id[25];
      int   i;

      scsi_cmd.inlen = 0;
      scsi_cmd.outlen = 40;
      scsi_cmd.cmd[0] = 0x12;       /* inquiry */
      scsi_cmd.cmd[1] = 0;
      scsi_cmd.cmd[2] = 0;
      scsi_cmd.cmd[3] = 0;
      scsi_cmd.cmd[4] = 40;
      scsi_cmd.cmd[5] = 0;

      seteuid(0);
      if (ioctl(fd,SCSI_IOCTL_SEND_COMMAND,(void *)&scsi_cmd)){
            sprintf( mesg, "inquiry ioctl error" );
            seteuid(getuid());
            return( 0 );
      }

      seteuid(getuid());
      for(i=0;i<24;i++) id[i] = scsi_cmd.cmd[i+8];
      id[24] = 0;

      sprintf( mesg, "%s", id );
      if( !strncmp(id,"IOMEGA  ZIP",11) ) return (1);
      else if( !strncmp(id,"iomega  jaz",11) ) return (2);
      else return (0);
}

int   motor( int fd, int mode )

{     scsi_cmd.inlen = 0;
      scsi_cmd.outlen = 0;
      scsi_cmd.cmd[0] = 0x1b;       /* start/stop */
      scsi_cmd.cmd[1] = 0;
      scsi_cmd.cmd[2] = 0;
      scsi_cmd.cmd[3] = 0;
      scsi_cmd.cmd[4] = mode;
      scsi_cmd.cmd[5] = 0;

      seteuid(0);
      if (ioctl(fd,SCSI_IOCTL_SEND_COMMAND,(void *)&scsi_cmd)) {
            sprintf( mesg, "motor control ioctl error");
            seteuid(getuid());
            return (0);
      }
      seteuid(getuid());
      return (1);
}

int   unlockdoor( int fd )

{     scsi_cmd.inlen = 0;
      scsi_cmd.outlen = 0;
      scsi_cmd.cmd[0] = 0x1e;       /* prevent/allow media removal */
      scsi_cmd.cmd[1] = 0;
      scsi_cmd.cmd[2] = 0;
      scsi_cmd.cmd[3] = 0;
      scsi_cmd.cmd[4] = 0;
      scsi_cmd.cmd[5] = 0;

      seteuid(0);
      if(ioctl(fd,SCSI_IOCTL_SEND_COMMAND,(void *)&scsi_cmd)) {
            sprintf( mesg, "door unlock ioctl error");
            seteuid(getuid());
            return (0);
      }
      seteuid(getuid());
      return (1);
}

int z_eject ( char *dev )

{  int      fd;

      if ((fd = open_dev (dev)))
            if (unlockdoor(fd))
                  if (motor(fd,1))
                        if (motor(fd,2)) {
                              close (fd);
                              return (1);
                        }
      close (fd);
      return (0);
}

int   get_prot_mode( int fd )

{  scsi_cmd.inlen = 0;
      scsi_cmd.outlen = 256;
      scsi_cmd.cmd[0] = 6;          /* Iomega non-sense command */
      scsi_cmd.cmd[1] = 0;
      scsi_cmd.cmd[2] = 2;
      scsi_cmd.cmd[3] = 0;
      scsi_cmd.cmd[4] = 128;
      scsi_cmd.cmd[5] = 0;

      seteuid(0);
      if (ioctl(fd,SCSI_IOCTL_SEND_COMMAND,(void *)&scsi_cmd)){
            sprintf( mesg, "non-sense ioctl error");
            seteuid(getuid());
            return( -1 );
      }

      seteuid(getuid());
      return (scsi_cmd.cmd[21] & 0x0f);   /* protection code */
}

int  dostatus( char * dev )   /* explain protection codes */

{     int   s, fd;

      if (!(fd = open_dev (dev))) return (-1);
      s = get_prot_mode(fd);

      if (s == 0) sprintf(mesg, "%s is not write-protected",dev);
      if (s == 2) sprintf(mesg, "%s is write-protected",dev);
      if (s == 3) sprintf(mesg, "%s is password write-protected",dev);
      close (fd);
      return (s);
}

void  pmode ( char *dev, int mode )

{     int   i, oldmode, len, fd;
      char  pw[34];

      if (!(fd = open_dev (dev))) return;
      pw[0]=0;
      oldmode = get_prot_mode(fd);
      if ((1 & mode) || (1 & oldmode)) {
        printf("Password: ");
        fgets(pw,33,stdin);
        len = strlen(pw);
        if ((len > 0) && (pw[len-1] == '\n')) pw[len-1] = 0;
      }
      len = strlen(pw);

      scsi_cmd.inlen = len;
      scsi_cmd.outlen = 0;
      scsi_cmd.cmd[0] = 0x0c;
      scsi_cmd.cmd[1] = mode;
      scsi_cmd.cmd[2] = 0;
      scsi_cmd.cmd[3] = 0;
      scsi_cmd.cmd[4] = len;
      scsi_cmd.cmd[5] = 0;

      for(i=0;i<len;i++) scsi_cmd.cmd[6+i] = pw[i];

      seteuid(0);
      if (ioctl(fd,SCSI_IOCTL_SEND_COMMAND,(void *)&scsi_cmd)) {
            sprintf( mesg, "set protection mode ioctl error");
            close (fd);
            seteuid(getuid());
            return;
      }
      close (fd);
      seteuid(getuid());

      dostatus (dev);
      z_eject (dev);    /* so linux can reset the wp mode */
}

int   open_dev( char *dev )
{
      int   zfd;

      seteuid(0);
      zfd = open (dev,0);
      if (zfd < 0){
            sprintf (mesg, "unable to open device %s.", dev);
            seteuid(getuid());
            return (0);;
      }
      seteuid(getuid());
      return (zfd);
}

int   check_scsi_dev( char *rsd, FD_jazip *fd_jazip )
{
      int         zfd;

      if (!is_raw_scsi(dev)) {
            printf ("%s is not a raw scsi device\n", dev);
            return (0);
      }
      if (!(zfd = open_dev (dev))){
            printf ("Can't open device %s.\n", dev);
            printf ("Is there a disk in the drive?\n");
            return (0);
      }
      if (! (dtype=is_jazip(zfd))) {
            printf ("%s\n", mesg);
            printf ("Unable to identify an IOMEGA drive on %s\n", dev);
            return (0);
      }
      if (dtype == ZIP){
            show_zip_icons (fd_jazip);
      }
      if (dtype == JAZ){
            show_jaz_icons (fd_jazip);
      }
      close (zfd);
      return( 1 );
}

Generated by  Doxygen 1.6.0   Back to index