mt.c revision 5988135d82ecba94b97669a9f2b7016b58ad691e
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* mt -- magnetic tape manipulation program
*/
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
/*
* This can't be DEFTAPE in mtio.h because that is currently the rewinding
* unit which makes 'mt fsf' a questionable activity at best.
*/
#define DEFAULT_NRW_TAPE "/dev/rmt/0n"
static int mtfd;
static void print_config(void);
static char *tape;
/* Pseudo flag for open even if drive is not ready (Unloaded) or reserved */
static struct commands {
char *c_name;
int c_code;
int c_oflag;
int c_usecnt;
} com[] = {
{ 0 }
};
#ifdef sun
#endif /* sun */
int
{
char *cp;
argc -= 2;
argv += 2;
} else
if (argc < 2) {
"usage: mt [ -f device ] command [ count ]\n");
exit(1);
}
break;
exit(1);
}
/*
* Provide additional error message decoding since
* we need additional error codes to fix them problem.
*/
"%s: no tape loaded or drive offline\n",
tape);
"%s: write protected or reserved.\n", tape);
} else {
}
exit(1);
}
/*
* Handle all MTIOC ioctls used in
*/
perror("mt");
exit(2);
}
/*
* Handle absolute file positioning. Ask tape driver
* where tape is and then skip to desired file. If
* driver doesn't support get location ioctl, rewind
* the tape and then space to the desired file.
*/
int usecnt;
int mt_fileno;
if (mt_fileno < 0) {
exit(1);
}
perror("mt");
exit(2);
}
/*
* Check if device supports reporting current file
* tape file position. If not, rewind the tape, and
* space forward.
*/
/* printf("mt: rewind\n"); */
perror("mt");
exit(2);
}
}
/* printf("mt: bsf= %d\n", mt_com.mt_count); */
} else {
/* printf("mt: fsf= %d\n", mt_com.mt_count); */
}
perror("failed");
exit(2);
}
print_config();
/* Handle regular mag tape ioctls */
int usecnt;
exit(1);
}
perror("failed");
exit(2);
}
/* Handle status ioctl */
} else {
perror("mt");
exit(2);
}
}
return (0);
}
static void
print_config(void)
{
struct mtdrivetype mdt;
struct mtdrivetype_request mdt_req;
char cfgname[48];
char tmp[2];
char *name;
int i;
perror("mt config");
return;
}
/*
* remove trailing spaces from product id.
*/
for (i = VIDPIDLEN; i; i--) {
continue;
} else {
break;
}
}
/*
* If this is a generic name display the Vid and Pid instead.
*/
} else {
}
/*
* Attempt to create a configuration name using vid and pid.
*/
continue;
continue;
}
/*
* Don't want show some bits, ST_DYNAMIC is set in the driver
* so one can tell that its not a compiled in config.
* The ST_LONG_ERASE and ST_LONG_TIMEOUTS are not displayed
* becouse the timeout values below already reflect them being
* set.
* Also ST_KNOWS_MEDIA is not displayed as it can not be configured
* from an st.conf entry.
*/
(void) printf("4,0x%2.2X,0x%2.2X,0x%2.2X,0x%2.2X,%d,",
}
/*
* Interpret the status buffer returned
*/
static void
{
struct mtdrivetype mdt;
struct mtdrivetype_request mdt_req;
/*
* Make a call to MTIOCGETDRIVETYPE ioctl, Also use old method
* of MT_TAPE_INFO for now, but MT_TAPE_INFO should dissapear in 2.7
*/
(void) printf("Unconfigured Drive: ");
}
} else {
break;
}
}
}
/* Handle SCSI tape drives specially. */
name = "SCSI";
else
}
(void) printf(" sense key(0x%x)= %s residual= %ld ",
(void) printf(" file no= %ld block no= %ld\n",
(void) printf(" WORM media\n");
}
} else {
/* Handle non-SCSI drives here. */
(void) printf("unknown tape drive type (0x%x)\n",
return;
}
(void) putchar('\n');
}
}
#ifdef sun
/*
* Define SCSI sense key error messages.
*
* The first 16 sense keys are SCSI standard
* sense keys. The keys after this are
* Sun Specifice 'sense' keys- e.g., crap.
*/
static char *standard_sense_keys[16] = {
"No Additional Sense", /* 0x00 */
"Soft Error", /* 0x01 */
"Not Ready", /* 0x02 */
"Media Error", /* 0x03 */
"Hardware Error", /* 0x04 */
"Illegal Request", /* 0x05 */
"Unit Attention", /* 0x06 */
"Write Protected", /* 0x07 */
"Blank Check", /* 0x08 */
"Vendor Unique", /* 0x09 */
"Copy Aborted", /* 0x0a */
"Aborted Command", /* 0x0b */
"Equal Error", /* 0x0c */
"Volume Overflow", /* 0x0d */
"Miscompare Error", /* 0x0e */
"Reserved" /* 0x0f */
};
static char *sun_sense_keys[] = {
"fatal", /* 0x10 */
"timeout", /* 0x11 */
"EOF", /* 0x12 */
"EOT", /* 0x13 */
"length error", /* 0x14 */
"BOT", /* 0x15 */
"wrong tape media", /* 0x16 */
0
};
/*
* Return the text string associated with the sense key value.
*/
static char *
{
static char unknown[32];
short i;
return (standard_sense_keys[key_code]);
}
i = 0;
while (sun_sense_keys[i]) {
if ((i + 0x10) == key_code) {
return (sun_sense_keys[i]);
} else i++;
}
(unsigned int) key_code);
return (unknown);
}
#endif
/*
* Print a register a la the %b format of the kernel's printf
*/
static void
{
int i, any = 0;
char c;
(void) printf("%s = %o", s, v);
else
(void) printf("%s = %x", s, v);
bits++;
if (v && bits) {
(void) putchar('<');
while ((i = *bits++) != 0) {
if (v & (1 << (i-1))) {
if (any)
(void) putchar(',');
any = 1;
(void) putchar(c);
} else
;
}
(void) putchar('>');
}
}