home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
CMDS
/
mtools_3.6.src.lzh
/
MTOOLS_3.6
/
mzip.c
< prev
next >
Wrap
Text File
|
1997-11-12
|
8KB
|
347 lines
/*
* mzip.c
* Iomega Zip/Jaz drive tool
* change protection mode and eject disk
*/
/* mzip.c by Markus Gyger <mgyger@itr.ch> */
/* This code is based on ftp://gear.torque.net/pub/ziptool.c */
/* by Grant R. Guenther with the following copyright notice: */
/* (c) 1996 Grant R. Guenther, based on work of Itai Nahshon */
/* http://www.torque.net/ziptool.html */
#include "sysincludes.h"
#include "mtools.h"
#include "scsi.h"
#ifndef _PASSWORD_LEN
#define _PASSWORD_LEN 33
#endif
#ifdef linux
#include <linux/fs.h>
#endif
static void usage(void)
{
fprintf(stderr,
"Mtools version %s, dated %s\n",
mversion, mdate);
fprintf(stderr,
"Usage: %s [-V] [-q] [-e] [-r|-w|-p|-x] [drive:]\n"
"\t-q print status\n"
"\t-e eject disk\n"
"\t-f eject disk even when mounted\n"
"\t-r write protected (read-only)\n"
"\t-w not write-protected (read-write)\n"
"\t-p password write protected\n"
"\t-x password protected\n",
progname);
exit(1);
}
static int get_zip_status(int fd)
{
unsigned char status[128];
unsigned char cdb[6] = { 0x06, 0, 0x02, 0, sizeof status, 0 };
if (scsi_cmd(fd, cdb, 6, SCSI_IO_READ,
status, sizeof status) == -1) {
perror("status: ");
exit(1);
}
return status[21] & 0xf;
}
static int short_command(int fd, int cmd1, int cmd2, int cmd3, char *data)
{
unsigned char cdb[6] = { 0, 0, 0, 0, 0, 0 };
cdb[0] = cmd1;
cdb[1] = cmd2;
cdb[4] = cmd3;
return scsi_cmd(fd, cdb, 6, SCSI_IO_WRITE,
data, data ? strlen(data) : 0);
}
static int iomega_command(int fd, int mode, char *data)
{
return short_command(fd,
SCSI_IOMEGA, mode, data ? strlen(data) : 0,
data);
}
static int door_command(int fd, int cmd1, int cmd2)
{
return short_command(fd, cmd1, 0, cmd2, 0);
}
void mzip(int argc, char **argv, int type)
{
int c;
char drive;
device_t *dev;
int fd = -1;
char name[EXPAND_BUF];
enum { ZIP_NIX = 0,
ZIP_STATUS = 1 << 0,
ZIP_EJECT = 1 << 1,
ZIP_RW = 1 << 2,
ZIP_RO = 1 << 3,
ZIP_RO_PW = 1 << 4,
ZIP_PW = 1 << 5,
ZIP_FORCE = 1 << 6
} request = ZIP_NIX;
/* get command line options */
while ((c = getopt(argc, argv, "efpqrwx")) != EOF) {
switch (c) {
case 'f':
request |= ZIP_FORCE;
break;
case 'e': /* eject */
request |= ZIP_EJECT;
break;
case 'p': /* password read-only */
request |= ZIP_RO_PW;
break;
case 'q': /* status query */
request |= ZIP_STATUS;
break;
case 'r': /* read-only */
request |= ZIP_RO;
break;
case 'w': /* read-write */
request |= ZIP_RW;
break;
case 'x': /* password protected */
request |= ZIP_PW;
break;
default: /* unrecognized */
usage();
}
}
if (request == ZIP_NIX) request = ZIP_STATUS; /* default action */
if(!!(request & ZIP_RW) + !!(request & ZIP_RO) +
!!(request & ZIP_RO_PW) + !!(request & ZIP_PW) > 1)
usage();
if (argc - optind > 1 ||
(argc - optind == 1 &&
(!argv[optind][0] || argv[optind][1] != ':')))
usage();
drive = toupper(argc - optind == 1 ? argv[argc - 1][0] : 'a');
for (dev = devices; dev->name; dev++) {
unsigned char cdb[6] = { 0, 0, 0, 0, 0, 0 };
struct {
char type,
type_modifier,
scsi_version,
data_format,
length,
reserved1[2],
capabilities,
vendor[8],
product[16],
revision[4],
vendor_specific[20],
reserved2[40];
} inq_data;
if (dev->drive != drive)
continue;
expand(dev->name, name);
precmd(dev);
if(dev->privileged)
reclaim_privs();
fd = open(name, O_RDONLY | dev->mode);
if(dev->privileged)
drop_privs();
/* need readonly, else we can't
* open the drive on Solaris if
* write-protected */
if (fd == -1)
continue;
closeExec(fd);
if (!(request & (ZIP_RW | ZIP_RO | ZIP_RO_PW |
ZIP_PW | ZIP_STATUS)))
/* if no mode change or ZIP specific status is
* involved, the command (eject) is applicable
* on all drives */
break;
cdb[0] = SCSI_INQUIRY;
cdb[4] = sizeof inq_data;
if (scsi_cmd(fd, cdb, 6, SCSI_IO_READ,
&inq_data, sizeof inq_data) != 0) {
close(fd);
continue;
}
#ifdef DEBUG
fprintf(stderr, "device: %s\n\tvendor: %.8s\n\tproduct: %.16s\n"
"\trevision: %.4s\n", name, inq_data.vendor,
inq_data.product, inq_data.revision);
#endif /* DEBUG */
if (strncasecmp("IOMEGA ", inq_data.vendor,
sizeof inq_data.vendor) ||
(strncasecmp("ZIP 100 ",
inq_data.product, sizeof inq_data.product) &&
strncasecmp("JAZ 1GB ",
inq_data.product, sizeof inq_data.product))) {
/* debugging */
fprintf(stderr,"Skipping drive with vendor='");
fwrite(inq_data.vendor,1, sizeof(inq_data.vendor),
stderr);
fprintf(stderr,"' product='");
fwrite(inq_data.product,1, sizeof(inq_data.product),
stderr);
fprintf(stderr,"'\n");
/* end debugging */
close(fd);
continue;
}
break; /* found Zip/Jaz drive */
}
if (dev->drive == 0) {
fprintf(stderr, "%s: drive '%c:' is not a Zip or Jaz drive\n",
argv[0], drive);
exit(1);
}
if (request & (ZIP_RW | ZIP_RO | ZIP_RO_PW | ZIP_PW)) {
int ret;
char *passwd, dummy[1];
int newmode;
if (get_zip_status(fd) & 0x01) { /* unlock first */
char *s, *passwd;
passwd = getpass("Password: ");
if ((s = strchr(passwd, '\n'))) *s = '\0'; /* chomp */
if((ret=iomega_command(fd, 0, passwd))){
if (ret == -1) perror("passwd: ");
else fprintf(stderr, "wrong password\n");
exit(1);
}
if(get_zip_status(fd) & 0x01) {
fprintf(stderr, "wrong password\n");
exit(1);
}
}
if (request & (ZIP_RO_PW | ZIP_PW)) {
char first_try[_PASSWORD_LEN];
passwd = getpass("Enter new password:");
strncpy(first_try, passwd,_PASSWORD_LEN);
passwd = getpass("Re-type new password:");
if(strncmp(first_try, passwd, _PASSWORD_LEN)) {
fprintf(stderr,
"You mispelled it. Password not set.\n");
exit(1);
}
} else {
passwd = dummy;
dummy[0] = '\0';
}
switch (request &
(ZIP_RW | ZIP_RO | ZIP_RO_PW | ZIP_PW)) {
case ZIP_RW:
newmode = 0x00;
break;
case ZIP_RO:
newmode = 0x02;
break;
case ZIP_RO_PW:
newmode = 0x03;
break;
case ZIP_PW:
newmode = 0x05;
break;
default:
newmode = 0;
break;
}
if((ret=iomega_command(fd, newmode, passwd))){
if (ret == -1) perror("set passwd: ");
else fprintf(stderr, "password not changed\n");
exit(1);
}
#ifdef linux
ioctl(fd, BLKRRPART); /* revalidate the disk, so that the
kernel notices that its writable
status has changed */
#endif
}
if (request & ZIP_STATUS) {
int status;
switch (status = get_zip_status(fd)) {
case 0:
printf("Drive '%c:' is not write-protected\n",
drive);
break;
case 2:
printf("Drive '%c:' is write-protected\n",
drive);
break;
case 3:
printf("Drive '%c:' is password write-protected\n",
drive);
break;
case 5:
printf("Drive '%c:' is password protected\n",
drive);
break;
default:
printf("Unknown protection mode %d of drive '%c:'\n",
status, drive);
break;
}
}
if (request & ZIP_EJECT) {
if(request & ZIP_FORCE)
if(door_command(fd, SCSI_ALLOW_MEDIUM_REMOVAL, 0) < 0) {
perror("door unlock: ");
exit(1);
}
if(door_command(fd, SCSI_START_STOP, 1) < 0) {
perror("stop motor: ");
exit(1);
}
if(door_command(fd, SCSI_START_STOP, 2) < 0) {
perror("eject: ");
exit(1);
}
if(door_command(fd, SCSI_START_STOP, 2) < 0) {
perror("second eject: ");
exit(1);
}
}
close(fd);
exit(0);
}