714 lines
18 KiB
Diff
714 lines
18 KiB
Diff
|
--- Makefile.am
|
||
|
+++ Makefile.am
|
||
|
@@ -19,4 +19,4 @@
|
||
|
|
||
|
AUTOMAKE_OPTIONS = gnits 1.8 dist-bzip2 std-options
|
||
|
|
||
|
-SUBDIRS = doc headers lib rmt src po tests
|
||
|
+SUBDIRS = doc headers lib src po tests
|
||
|
--- doc/mt.1
|
||
|
+++ doc/mt.1
|
||
|
@@ -76,9 +76,6 @@
|
||
|
.IR count .
|
||
|
Equivalent to rewind followed by fsf
|
||
|
.IR count .
|
||
|
-.IP seek
|
||
|
-Seek to block number
|
||
|
-.IR count .
|
||
|
.IP eom
|
||
|
Space to the end of the recorded media on the tape
|
||
|
(for appending files onto tapes).
|
||
|
@@ -93,6 +90,69 @@
|
||
|
then rewind it again.
|
||
|
.IP erase
|
||
|
Erase the tape.
|
||
|
+.IP fss
|
||
|
+(SCSI tapes) Forward space
|
||
|
+.I count
|
||
|
+setmarks.
|
||
|
+.IP bss
|
||
|
+(SCSI tapes) Backward space
|
||
|
+.I count
|
||
|
+setmarks.
|
||
|
+.IP "wset"
|
||
|
+(SCSI tapes) Write
|
||
|
+.I count
|
||
|
+setmarks at current position (only SCSI tape).
|
||
|
+.IP "eod, seod"
|
||
|
+Space to end of valid data. Used on streamer tape
|
||
|
+drives to append data to the logical and of tape.
|
||
|
+.IP setblk
|
||
|
+(SCSI tapes) Set the block size of the drive to
|
||
|
+.I count
|
||
|
+bytes per record.
|
||
|
+.IP setdensity
|
||
|
+(SCSI tapes) Set the tape density code to
|
||
|
+.I count.
|
||
|
+The proper codes to use with each drive should be looked up from the
|
||
|
+drive documentation.
|
||
|
+.IP drvbuffer
|
||
|
+(SCSI tapes) Set the tape drive buffer code to
|
||
|
+.I number.
|
||
|
+The proper value for unbuffered operation is zero and "normal" buffered
|
||
|
+operation one. The meanings of other values can be found in the drive
|
||
|
+documentation or, in case of a SCSI-2 drive, from the SCSI-2 standard.
|
||
|
+.IP stoptions
|
||
|
+(SCSI tapes) Set the driver options bits to
|
||
|
+.I count
|
||
|
+for the device.
|
||
|
+The bits can be set by oring the following values: 1 to enable write
|
||
|
+buffering, 2 to enable asynchronous writes, 4 to enable read ahead,
|
||
|
+8 to enable debugging output (if it has been compiled to the driver).
|
||
|
+.IP stwrthreshold
|
||
|
+(SCSI tapes) The write threshold for the tape device is set to
|
||
|
+.I count
|
||
|
+kilobytes. The value must be smaller than or equal to the driver
|
||
|
+buffer size.
|
||
|
+.IP seek
|
||
|
+(SCSI tapes) Seek to the
|
||
|
+.I count
|
||
|
+block on the tape. This operation is available on some
|
||
|
+Tandberg and Wangtek streamers and some SCSI-2 tape drives.
|
||
|
+.IP tell
|
||
|
+(SCSI tapes) Tell the current block on tape. This operation is available on some
|
||
|
+Tandberg and Wangtek streamers and some SCSI-2 tape drives.
|
||
|
+.IP densities
|
||
|
+(SCSI tapes) Write explanation of some common density codes to
|
||
|
+standard output.
|
||
|
+.IP datcompression
|
||
|
+(some SCSI-2 DAT tapes) Inquire or set the compression status
|
||
|
+(on/off). If the
|
||
|
+.I count
|
||
|
+is one the compression status is printed. If the
|
||
|
+.I count
|
||
|
+is zero, compression is disabled. Otherwise, compression is
|
||
|
+enabled. The command uses the SCSI ioctl to read and write the Data
|
||
|
+Compression Characteristics mode page (15). ONLY ROOT CAN USE THIS
|
||
|
+COMMAND.
|
||
|
.PP
|
||
|
.B mt
|
||
|
exits with a status of 0 if the operation succeeded, 1 if the
|
||
|
--- lib/system.h
|
||
|
+++ lib/system.h
|
||
|
@@ -473,10 +473,11 @@
|
||
|
|
||
|
#if HAVE_LOCALE_H
|
||
|
# include <locale.h>
|
||
|
-#endif
|
||
|
+#else
|
||
|
#if !HAVE_SETLOCALE
|
||
|
# define setlocale(category, locale) /* empty */
|
||
|
#endif
|
||
|
+#endif
|
||
|
|
||
|
#include <time.h>
|
||
|
#if defined(HAVE_SYS_TIME_H) && defined(TIME_WITH_SYS_TIME)
|
||
|
--- src/Makefile.am
|
||
|
+++ src/Makefile.am
|
||
|
@@ -17,7 +17,7 @@
|
||
|
|
||
|
INCLUDES=-I. -I.. -I$(top_srcdir)/lib
|
||
|
|
||
|
-bin_PROGRAMS=cpio @CPIO_MT_PROG@
|
||
|
+bin_PROGRAMS=cpio mt
|
||
|
EXTRA_PROGRAMS=mt
|
||
|
|
||
|
cpio_SOURCES = \
|
||
|
--- src/copyin.c
|
||
|
+++ src/copyin.c
|
||
|
@@ -176,7 +176,7 @@
|
||
|
#endif
|
||
|
if (crc != file_hdr->c_chksum)
|
||
|
{
|
||
|
- error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
|
||
|
+ error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
|
||
|
file_hdr->c_name, crc, file_hdr->c_chksum);
|
||
|
}
|
||
|
}
|
||
|
@@ -541,7 +541,7 @@
|
||
|
if (archive_format == arf_crcascii)
|
||
|
{
|
||
|
if (crc != file_hdr->c_chksum)
|
||
|
- error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
|
||
|
+ error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
|
||
|
file_hdr->c_name, crc, file_hdr->c_chksum);
|
||
|
}
|
||
|
tape_skip_padding (in_file_des, file_hdr->c_filesize);
|
||
|
@@ -563,7 +563,7 @@
|
||
|
if (archive_format == arf_crcascii)
|
||
|
{
|
||
|
if (crc != file_hdr->c_chksum)
|
||
|
- error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
|
||
|
+ error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
|
||
|
file_hdr->c_name, crc, file_hdr->c_chksum);
|
||
|
}
|
||
|
|
||
|
@@ -825,7 +825,7 @@
|
||
|
static void
|
||
|
copyin_file (struct new_cpio_header* file_hdr, int in_file_des)
|
||
|
{
|
||
|
- int existing_dir;
|
||
|
+ int existing_dir=0;
|
||
|
|
||
|
if (!to_stdout_option
|
||
|
&& try_existing_file (file_hdr, in_file_des, &existing_dir) < 0)
|
||
|
@@ -897,7 +897,7 @@
|
||
|
}
|
||
|
tbuf[16] = '\0';
|
||
|
|
||
|
- printf ("%s %3u ", mbuf, file_hdr->c_nlink);
|
||
|
+ printf ("%s %3lu ", mbuf, file_hdr->c_nlink);
|
||
|
|
||
|
if (numeric_uid)
|
||
|
printf ("%-8u %-8u ", (unsigned int) file_hdr->c_uid,
|
||
|
@@ -908,7 +908,7 @@
|
||
|
|
||
|
if ((file_hdr->c_mode & CP_IFMT) == CP_IFCHR
|
||
|
|| (file_hdr->c_mode & CP_IFMT) == CP_IFBLK)
|
||
|
- printf ("%3u, %3u ", file_hdr->c_rdev_maj,
|
||
|
+ printf ("%3lu, %3lu ", file_hdr->c_rdev_maj,
|
||
|
file_hdr->c_rdev_min);
|
||
|
else
|
||
|
printf ("%8lu ", file_hdr->c_filesize);
|
||
|
@@ -1342,14 +1342,15 @@
|
||
|
process_copy_in ()
|
||
|
{
|
||
|
char done = false; /* True if trailer reached. */
|
||
|
- FILE *tty_in; /* Interactive file for rename option. */
|
||
|
- FILE *tty_out; /* Interactive file for rename option. */
|
||
|
- FILE *rename_in; /* Batch file for rename option. */
|
||
|
+ FILE *tty_in=NULL; /* Interactive file for rename option. */
|
||
|
+ FILE *tty_out=NULL; /* Interactive file for rename option. */
|
||
|
+ FILE *rename_in=NULL; /* Batch file for rename option. */
|
||
|
struct stat file_stat; /* Output file stat record. */
|
||
|
struct new_cpio_header file_hdr; /* Output header information. */
|
||
|
int in_file_des; /* Input file descriptor. */
|
||
|
char skip_file; /* Flag for use with patterns. */
|
||
|
int i; /* Loop index variable. */
|
||
|
+ int lastpattern = 0;
|
||
|
|
||
|
/* Initialize the copy in. */
|
||
|
if (pattern_file_name)
|
||
|
@@ -1477,8 +1478,10 @@
|
||
|
for (i = 0; i < num_patterns
|
||
|
&& skip_file == copy_matching_files; i++)
|
||
|
{
|
||
|
- if (fnmatch (save_patterns[i], file_hdr.c_name, 0) == 0)
|
||
|
+ if (fnmatch (save_patterns[lastpattern], file_hdr.c_name, 0) == 0)
|
||
|
skip_file = !copy_matching_files;
|
||
|
+ else if (++lastpattern >= num_patterns)
|
||
|
+ lastpattern = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -1530,7 +1533,7 @@
|
||
|
tape_skip_padding (in_file_des, file_hdr.c_filesize);
|
||
|
if (crc != file_hdr.c_chksum)
|
||
|
{
|
||
|
- error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
|
||
|
+ error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
|
||
|
file_hdr.c_name, crc, file_hdr.c_chksum);
|
||
|
}
|
||
|
/* Debian hack: -v and -V now work with --only-verify-crc.
|
||
|
--- src/mt.c
|
||
|
+++ src/mt.c
|
||
|
@@ -16,6 +16,10 @@
|
||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||
|
*/
|
||
|
|
||
|
+/* Modified for the Linux SCSI tape driver by Brian Mays from code
|
||
|
+ written by Kai Makisara.
|
||
|
+ Last Modified: Tue Apr 23 15:37:54 EDT 1996
|
||
|
+*/
|
||
|
|
||
|
/* If -f is not given, the environment variable TAPE is used;
|
||
|
if that is not set, a default device defined in sys/mtio.h is used.
|
||
|
@@ -50,6 +54,46 @@
|
||
|
retension Rewind the tape, then wind it to the end of the reel,
|
||
|
then rewind it again.
|
||
|
erase Erase the tape.
|
||
|
+ fss (SCSI tapes) Forward space COUNT setmarks.
|
||
|
+ bss (SCSI tapes) Backward space COUNT setmarks.
|
||
|
+ wset (SCSI tapes) Write COUNT setmarks at current position
|
||
|
+ (only SCSI tape).
|
||
|
+ eod, seod Space to end of valid data. Used on streamer tape
|
||
|
+ drives to append data to the logical and of tape.
|
||
|
+ setblk (SCSI tapes) Set the block size of the drive to COUNT
|
||
|
+ bytes per record.
|
||
|
+ setdensity (SCSI tapes) Set the tape density code to COUNT. The
|
||
|
+ proper codes to use with each drive should be looked
|
||
|
+ up from the drive documentation.
|
||
|
+ drvbuffer (SCSI tapes) Set the tape drive buffer code to
|
||
|
+ NUMBER. The proper value for unbuffered operation is
|
||
|
+ zero and "normal" buffered operation one. The meanings
|
||
|
+ of other values can be found in the drive
|
||
|
+ documentation or, in case of a SCSI-2 drive, from the
|
||
|
+ SCSI-2 standard.
|
||
|
+ stoptions (SCSI tapes) Set the driver options bits to COUNT for
|
||
|
+ the device. The bits can be set by oring the
|
||
|
+ following values: 1 to enable write buffering, 2 to
|
||
|
+ enable asynchronous writes, 4 to enable read ahead, 8
|
||
|
+ to enable debugging output (if it has been compiled to
|
||
|
+ the driver).
|
||
|
+ stwrthreshold
|
||
|
+ (SCSI tapes) The write threshold for the tape device
|
||
|
+ is set to COUNT kilobytes. The value must be smaller
|
||
|
+ than or equal to the driver buffer size.
|
||
|
+ seek (SCSI tapes) Seek to the COUNT block on the tape.
|
||
|
+ This operation is available on some Tandberg and
|
||
|
+ Wangtek streamers and some SCSI-2 tape drives.
|
||
|
+ tell (SCSI tapes) Tell the current block on tape. This
|
||
|
+ operation is available on some Tandberg and Wangtek
|
||
|
+ streamers and some SCSI-2 tape drives.
|
||
|
+ densities (SCSI tapes) Write explanation of some common density
|
||
|
+ codes to standard output.
|
||
|
+ datcompression
|
||
|
+ (some SCSI-2 DAT tapes) Inquire or set the compression
|
||
|
+ status (on/off). If the COUNT is one the compression
|
||
|
+ status is printed. If the COUNT is zero, compression
|
||
|
+ is disabled. Otherwise, compression is enabled.
|
||
|
|
||
|
David MacKenzie <djm@gnu.ai.mit.edu> */
|
||
|
|
||
|
@@ -104,6 +148,45 @@
|
||
|
void exit ();
|
||
|
#endif
|
||
|
|
||
|
+#include "../lib/argmatch.h"
|
||
|
+
|
||
|
+#if defined(linux) || defined(__linux)
|
||
|
+#define MTDATCOMP 1000 /* Random unused number. */
|
||
|
+#define MTDENS 1001 /* Random unused number. */
|
||
|
+
|
||
|
+struct densities {
|
||
|
+ int code;
|
||
|
+ char *name;
|
||
|
+} density_tbl[] = {
|
||
|
+ {0x00, "default"},
|
||
|
+ {0x01, "NRZI (800 bpi)"},
|
||
|
+ {0x02, "PE (1600 bpi)"},
|
||
|
+ {0x03, "GCR (6250 bpi)"},
|
||
|
+ {0x05, "QIC-45/60 (GCR, 8000 bpi)"},
|
||
|
+ {0x06, "PE (3200 bpi)"},
|
||
|
+ {0x07, "IMFM (6400 bpi)"},
|
||
|
+ {0x08, "GCR (8000 bpi)"},
|
||
|
+ {0x09, "GCR /37871 bpi)"},
|
||
|
+ {0x0a, "MFM (6667 bpi)"},
|
||
|
+ {0x0b, "PE (1600 bpi)"},
|
||
|
+ {0x0c, "GCR (12960 bpi)"},
|
||
|
+ {0x0d, "GCR (25380 bpi)"},
|
||
|
+ {0x0f, "QIC-120 (GCR 10000 bpi)"},
|
||
|
+ {0x10, "QIC-150/250 (GCR 10000 bpi)"},
|
||
|
+ {0x11, "QIC-320/525 (GCR 16000 bpi)"},
|
||
|
+ {0x12, "QIC-1350 (RLL 51667 bpi)"},
|
||
|
+ {0x13, "DDS (61000 bpi)"},
|
||
|
+ {0x14, "EXB-8200 (RLL 43245 bpi)"},
|
||
|
+ {0x15, "EXB-8500 (RLL 45434 bpi)"},
|
||
|
+ {0x16, "MFM 10000 bpi"},
|
||
|
+ {0x17, "MFM 42500 bpi"},
|
||
|
+ {0x24, "DDS-2"},
|
||
|
+ {140, "EXB-8505 compressed"},
|
||
|
+ {144, "EXB-8205 compressed"},
|
||
|
+ {-1, NULL}};
|
||
|
+#endif
|
||
|
+
|
||
|
+
|
||
|
char *opnames[] =
|
||
|
{
|
||
|
"eof", "weof", "fsf", "bsf", "fsr", "bsr",
|
||
|
@@ -113,6 +196,8 @@
|
||
|
#endif
|
||
|
#ifdef MTEOM
|
||
|
"eom",
|
||
|
+ "eod",
|
||
|
+ "seod",
|
||
|
#endif
|
||
|
#ifdef MTRETEN
|
||
|
"retension",
|
||
|
@@ -127,6 +212,39 @@
|
||
|
#ifdef MTSEEK
|
||
|
"seek",
|
||
|
#endif
|
||
|
+#ifdef MTTELL
|
||
|
+ "tell",
|
||
|
+#endif
|
||
|
+#ifdef MTFSS
|
||
|
+ "fss",
|
||
|
+#endif
|
||
|
+#ifdef MTBSS
|
||
|
+ "bss",
|
||
|
+#endif
|
||
|
+#ifdef MTWSM
|
||
|
+ "wset",
|
||
|
+#endif
|
||
|
+#ifdef MTSETBLK
|
||
|
+ "setblk",
|
||
|
+#endif
|
||
|
+#ifdef MTSETDENSITY
|
||
|
+ "setdensity",
|
||
|
+#endif
|
||
|
+#ifdef MTSETDRVBUFFER
|
||
|
+ "drvbuffer",
|
||
|
+#ifdef MT_ST_BOOLEANS
|
||
|
+ "stoptions",
|
||
|
+#endif
|
||
|
+#ifdef MT_ST_WRITE_THRESHOLD
|
||
|
+ "stwrthreshold",
|
||
|
+#endif
|
||
|
+#endif
|
||
|
+#ifdef MTDATCOMP
|
||
|
+ "datcompression",
|
||
|
+#endif
|
||
|
+#ifdef MTDENS
|
||
|
+ "densities",
|
||
|
+#endif
|
||
|
NULL
|
||
|
};
|
||
|
|
||
|
@@ -140,6 +258,8 @@
|
||
|
#endif
|
||
|
#ifdef MTEOM
|
||
|
MTEOM,
|
||
|
+ MTEOM,
|
||
|
+ MTEOM,
|
||
|
#endif
|
||
|
#ifdef MTRETEN
|
||
|
MTRETEN,
|
||
|
@@ -154,9 +274,69 @@
|
||
|
#ifdef MTSEEK
|
||
|
MTSEEK,
|
||
|
#endif
|
||
|
+#ifdef MTTELL
|
||
|
+ MTTELL,
|
||
|
+#endif
|
||
|
+#ifdef MTFSS
|
||
|
+ MTFSS,
|
||
|
+#endif
|
||
|
+#ifdef MTBSS
|
||
|
+ MTBSS,
|
||
|
+#endif
|
||
|
+#ifdef MTWSM
|
||
|
+ MTWSM,
|
||
|
+#endif
|
||
|
+#ifdef MTSETBLK
|
||
|
+ MTSETBLK,
|
||
|
+#endif
|
||
|
+#ifdef MTSETDENSITY
|
||
|
+ MTSETDENSITY,
|
||
|
+#endif
|
||
|
+#ifdef MTSETDRVBUFFER
|
||
|
+ MTSETDRVBUFFER,
|
||
|
+#ifdef MT_ST_BOOLEANS
|
||
|
+ MTSETDRVBUFFER,
|
||
|
+#endif
|
||
|
+#ifdef MT_ST_WRITE_THRESHOLD
|
||
|
+ MTSETDRVBUFFER,
|
||
|
+#endif
|
||
|
+#endif
|
||
|
+#ifdef MTDATCOMP
|
||
|
+ MTDATCOMP,
|
||
|
+#endif
|
||
|
+#ifdef MTDENS
|
||
|
+ MTDENS,
|
||
|
+#endif
|
||
|
+ 0
|
||
|
+};
|
||
|
+
|
||
|
+char *cbnames[] =
|
||
|
+{
|
||
|
+#ifdef MT_ST_BOOLEANS
|
||
|
+ "stoptions",
|
||
|
+#endif
|
||
|
+#ifdef MT_ST_WRITE_THRESHOLD
|
||
|
+ "stwrthreshold",
|
||
|
+#endif
|
||
|
+ NULL
|
||
|
+};
|
||
|
+
|
||
|
+int count_bits[] =
|
||
|
+{
|
||
|
+#ifdef MT_ST_BOOLEANS
|
||
|
+ MT_ST_BOOLEANS,
|
||
|
+#endif
|
||
|
+#ifdef MT_ST_WRITE_THRESHOLD
|
||
|
+ MT_ST_WRITE_THRESHOLD,
|
||
|
+#endif
|
||
|
0
|
||
|
};
|
||
|
|
||
|
+#ifdef MT_TAPE_INFO
|
||
|
+ struct mt_tape_info tapes[] = MT_TAPE_INFO;
|
||
|
+#endif
|
||
|
+
|
||
|
+
|
||
|
struct option longopts[] =
|
||
|
{
|
||
|
{"file", 1, NULL, 'f'},
|
||
|
@@ -199,10 +379,22 @@
|
||
|
print_status (char *dev, int desc)
|
||
|
{
|
||
|
struct mtget status;
|
||
|
+#ifdef MT_TAPE_INFO
|
||
|
+ struct mt_tape_info *mt;
|
||
|
+#endif
|
||
|
|
||
|
if (rmtioctl (desc, MTIOCGET, (char*)&status) == -1)
|
||
|
error (2, errno, "%s", dev);
|
||
|
|
||
|
+#ifdef MT_TAPE_INFO
|
||
|
+ for (mt = tapes; mt->t_type; mt++)
|
||
|
+ if (mt->t_type == status.mt_type) break;
|
||
|
+ if (mt->t_type != 0)
|
||
|
+ {
|
||
|
+ printf ("drive type = %s\n", mt->t_name);
|
||
|
+ }
|
||
|
+ else
|
||
|
+#endif
|
||
|
printf ("drive type = %d\n", (int) status.mt_type);
|
||
|
#if defined(hpux) || defined(__hpux)
|
||
|
printf ("drive status (high) = %d\n", (int) status.mt_dsreg1);
|
||
|
@@ -216,8 +408,178 @@
|
||
|
printf ("file number = %d\n", (int) status.mt_fileno);
|
||
|
printf ("block number = %d\n", (int) status.mt_blkno);
|
||
|
#endif
|
||
|
+#if defined(linux) || defined(__linux)
|
||
|
+ if (status.mt_type == MT_ISSCSI1 ||
|
||
|
+ status.mt_type == MT_ISSCSI2)
|
||
|
+ {
|
||
|
+ int dens, i;
|
||
|
+ char *density;
|
||
|
+ dens = (status.mt_dsreg & MT_ST_DENSITY_MASK) >> MT_ST_DENSITY_SHIFT;
|
||
|
+ density = "unknown";
|
||
|
+ for (i=0; density_tbl[i].code >= 0; i++)
|
||
|
+ if (density_tbl[i].code == dens)
|
||
|
+ {
|
||
|
+ density = density_tbl[i].name;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ printf("Tape block size %ld bytes. Density code 0x%x (%s).\n",
|
||
|
+ ((status.mt_dsreg & MT_ST_BLKSIZE_MASK) >> MT_ST_BLKSIZE_SHIFT),
|
||
|
+ dens, density);
|
||
|
+
|
||
|
+ printf("Soft error count since last status=%ld\n",
|
||
|
+ (status.mt_erreg & MT_ST_SOFTERR_MASK) >> MT_ST_SOFTERR_SHIFT);
|
||
|
+ printf("General status bits on (%lx):\n", status.mt_gstat);
|
||
|
+ if (GMT_EOF(status.mt_gstat))
|
||
|
+ printf(" EOF");
|
||
|
+ if (GMT_BOT(status.mt_gstat))
|
||
|
+ printf(" BOT");
|
||
|
+ if (GMT_EOT(status.mt_gstat))
|
||
|
+ printf(" EOT");
|
||
|
+ if (GMT_SM(status.mt_gstat))
|
||
|
+ printf(" SM");
|
||
|
+ if (GMT_EOD(status.mt_gstat))
|
||
|
+ printf(" EOD");
|
||
|
+ if (GMT_WR_PROT(status.mt_gstat))
|
||
|
+ printf(" WR_PROT");
|
||
|
+ if (GMT_ONLINE(status.mt_gstat))
|
||
|
+ printf(" ONLINE");
|
||
|
+ if (GMT_D_6250(status.mt_gstat))
|
||
|
+ printf(" D_6250");
|
||
|
+ if (GMT_D_1600(status.mt_gstat))
|
||
|
+ printf(" D_1600");
|
||
|
+ if (GMT_D_800(status.mt_gstat))
|
||
|
+ printf(" D_800");
|
||
|
+ if (GMT_DR_OPEN(status.mt_gstat))
|
||
|
+ printf(" DR_OPEN");
|
||
|
+ if (GMT_IM_REP_EN(status.mt_gstat))
|
||
|
+ printf(" IM_REP_EN");
|
||
|
+ if (status.mt_gstat != 0)
|
||
|
+ putchar ('\n');
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ printf("gstat = %0lx\n", status.mt_gstat);
|
||
|
+ }
|
||
|
+#endif
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+#if defined(linux) || defined(__linux)
|
||
|
+/*** Get and set the DAT compression (Mode Page 15) ***/
|
||
|
+
|
||
|
+#define MODE_SENSE 0x1a
|
||
|
+#define MODE_SELECT 0x15
|
||
|
+
|
||
|
+int
|
||
|
+read_mode_page(int fn, int page, int length, unsigned char *buffer,
|
||
|
+ int do_mask)
|
||
|
+{
|
||
|
+ int result, *ip;
|
||
|
+ unsigned char tmpbuffer[30], *cmd;
|
||
|
+
|
||
|
+ memset(tmpbuffer, 0, 14);
|
||
|
+ ip = (int *)&(tmpbuffer[0]);
|
||
|
+ *ip = 0;
|
||
|
+ *(ip+1) = length + 4;
|
||
|
+
|
||
|
+ cmd = &(tmpbuffer[8]);
|
||
|
+ cmd[0] = MODE_SENSE;
|
||
|
+ cmd[1] = 8;
|
||
|
+ cmd[2] = page;
|
||
|
+ if (do_mask)
|
||
|
+ cmd[2] |= 0x40; /* Get changeable parameter mask */
|
||
|
+ cmd[4] = length + 4;
|
||
|
+
|
||
|
+ result = ioctl(fn, 1, tmpbuffer);
|
||
|
+ if (result) {
|
||
|
+ fprintf(stderr, "Can't read mode page. Are you sure you are root?\n");
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ memcpy(buffer, tmpbuffer + 8, length + 4);
|
||
|
+ return 1;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+int
|
||
|
+write_mode_page(int fn, int page, int length, unsigned char *buffer)
|
||
|
+{
|
||
|
+ int result, *ip;
|
||
|
+ unsigned char tmpbuffer[40], *cmd;
|
||
|
+
|
||
|
+ memset(tmpbuffer, 0, 14);
|
||
|
+ ip = (int *)&(tmpbuffer[0]);
|
||
|
+ *ip = length + 4;
|
||
|
+ *(ip+1) = 0;
|
||
|
+
|
||
|
+ cmd = &(tmpbuffer[8]);
|
||
|
+ cmd[0] = MODE_SELECT;
|
||
|
+ cmd[1] = 0x10;
|
||
|
+ cmd[4] = length + 4;
|
||
|
+
|
||
|
+ memcpy(tmpbuffer + 14, buffer, length + 4);
|
||
|
+ tmpbuffer[14] = 0; /* reserved data length */
|
||
|
+ tmpbuffer[18] &= 0x3f; /* reserved bits in page code byte */
|
||
|
+
|
||
|
+ result = ioctl(fn, 1, tmpbuffer);
|
||
|
+ if (result) {
|
||
|
+ fprintf(stderr, "Can't write mode page.\n");
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ return 1;
|
||
|
}
|
||
|
|
||
|
+
|
||
|
+int
|
||
|
+do_dat_compression(char *dev, int fn, int count)
|
||
|
+{
|
||
|
+ int i;
|
||
|
+ unsigned char buffer[30], mask[30];
|
||
|
+
|
||
|
+ if (!read_mode_page(fn, 0x0f, 16, buffer, 0)) {
|
||
|
+ error (2, errno, "%s", dev);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (count != 1) {
|
||
|
+ if (count == 0)
|
||
|
+ buffer[4+2] &= 0x7f;
|
||
|
+ else
|
||
|
+ buffer[4+2] |= 0x80;
|
||
|
+ if (read_mode_page(fn, 0x0f, 16, mask, 1))
|
||
|
+ for (i=2; i < 16; i++)
|
||
|
+ buffer[4+i] |= mask[4+i];
|
||
|
+ if (!write_mode_page(fn, 0x0f, 16, buffer)) {
|
||
|
+ error (2, errno, "%s", dev);
|
||
|
+ }
|
||
|
+ if (!read_mode_page(fn, 0x0f, 16, buffer, 0)) { /* Re-read to check */
|
||
|
+ error (2, errno, "%s", dev);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (buffer[4+2] & 0x80)
|
||
|
+ printf("Compression on.\n");
|
||
|
+ else
|
||
|
+ printf("Compression off.\n");
|
||
|
+
|
||
|
+ return 1;
|
||
|
+}
|
||
|
+#endif
|
||
|
+
|
||
|
+#ifdef MTTELL
|
||
|
+void
|
||
|
+print_position (dev, desc)
|
||
|
+ char *dev;
|
||
|
+ int desc;
|
||
|
+{
|
||
|
+ struct mtpos position;
|
||
|
+
|
||
|
+ if (rmtioctl (desc, MTIOCPOS, &position) == -1)
|
||
|
+ error (2, errno, "%s", dev);
|
||
|
+ printf("At block %ld.\n", position.mt_blkno);
|
||
|
+
|
||
|
+}
|
||
|
+#endif
|
||
|
+
|
||
|
+
|
||
|
void
|
||
|
usage (FILE *fp,int status)
|
||
|
{
|
||
|
@@ -277,7 +639,7 @@
|
||
|
if (optind == argc)
|
||
|
usage (stderr, 1);
|
||
|
|
||
|
- i = argmatch (argv[optind], opnames);
|
||
|
+ i = argmatch (argv[optind], opnames,NULL,0);
|
||
|
if (i < 0)
|
||
|
{
|
||
|
invalid_arg ("tape operation", argv[optind], i);
|
||
|
@@ -309,10 +671,29 @@
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
+#ifdef MTDENS
|
||
|
+ if (operation == MTDENS)
|
||
|
+ {
|
||
|
+ printf("Some SCSI tape density codes:\ncode explanation\n");
|
||
|
+ for (i=0; density_tbl[i].code >= 0; i++)
|
||
|
+ printf("0x%02x %s\n", density_tbl[i].code, density_tbl[i].name);
|
||
|
+ exit (0);
|
||
|
+ }
|
||
|
+#endif
|
||
|
+
|
||
|
if ( (operation == MTWEOF)
|
||
|
#ifdef MTERASE
|
||
|
|| (operation == MTERASE)
|
||
|
#endif
|
||
|
+#ifdef MTWSM
|
||
|
+ || (operation == MTWSM)
|
||
|
+#endif
|
||
|
+#ifdef MTSETDRVBUFFER
|
||
|
+ || (operation == MTSETDRVBUFFER)
|
||
|
+#endif
|
||
|
+#ifdef MTDATCOMP
|
||
|
+ || (operation == MTDATCOMP)
|
||
|
+#endif
|
||
|
)
|
||
|
tapedesc = rmtopen (tapedev, O_WRONLY, 0, rsh_command_option);
|
||
|
else
|
||
|
@@ -321,6 +702,17 @@
|
||
|
error (1, errno, "%s", tapedev);
|
||
|
check_type (tapedev, tapedesc);
|
||
|
|
||
|
+#ifdef MTDATCOMP
|
||
|
+ if (operation == MTDATCOMP)
|
||
|
+ do_dat_compression(tapedev, tapedesc, count);
|
||
|
+ else
|
||
|
+#endif
|
||
|
+#ifdef MTTELL
|
||
|
+ if (operation == MTTELL)
|
||
|
+ print_position (tapedev, tapedesc);
|
||
|
+ else
|
||
|
+#endif
|
||
|
+ {
|
||
|
if (operation == MTASF)
|
||
|
{
|
||
|
perform_operation (tapedev, tapedesc, MTREW, 1);
|
||
|
@@ -329,6 +721,7 @@
|
||
|
perform_operation (tapedev, tapedesc, operation, count);
|
||
|
if (operation == MTNOP)
|
||
|
print_status (tapedev, tapedesc);
|
||
|
+ }
|
||
|
|
||
|
if (rmtclose (tapedesc) == -1)
|
||
|
error (2, errno, "%s", tapedev);
|