⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mt.c

📁 mt 是linux下得磁带机
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	This file contains the source of the 'mt' program intended for	Linux systems. The program supports the basic mt commands found	in most Unix-like systems. In addition to this the program	supports several commands designed for use with the Linux SCSI	tape drive.	Maintained by Kai M鋕isara (email Kai.Makisara@kolumbus.fi)	Copyright by Kai M鋕isara, 1998 - 2005. The program may be distributed	according to the GNU Public License	Last Modified: Sun Aug 21 21:48:06 2005 by kai.makisara*/#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <sys/types.h>#include <sys/ioctl.h>#include "mtio.h"#ifndef DEFTAPE#define DEFTAPE "/dev/tape"     /* default tape device */#endif /* DEFTAPE */#define VERSION "0.9b"typedef int (* cmdfunc)(/* int, struct cmdef_tr *, int, char ** */);typedef struct cmdef_tr {    char *cmd_name;    int cmd_code;    cmdfunc cmd_function;    int cmd_count_bits;    unsigned char cmd_fdtype;    unsigned char arg_cnt;    int error_tests;} cmdef_tr;#define NO_FD      0#define FD_RDONLY  1#define FD_RDWR    2#define NO_ARGS       0#define ONE_ARG       1#define TWO_ARGS      2#define MULTIPLE_ARGS 255#define DO_BOOLEANS    1002#define SET_BOOLEANS   1003#define CLEAR_BOOLEANS 1004#define ET_ONLINE    1#define ET_WPROT     2static void usage(int);static int do_standard(int, cmdef_tr *, int, char **);static int do_drvbuffer(int, cmdef_tr *, int, char **);static int do_options(int, cmdef_tr *, int, char **);static int do_tell(int, cmdef_tr *, int, char **);static int do_partseek(int, cmdef_tr *, int, char **);static int do_status(int, cmdef_tr *, int, char **);static int print_densities(int, cmdef_tr *, int, char **);static int do_asf(int, cmdef_tr *, int, char **);static void test_error(int, cmdef_tr *);static cmdef_tr cmds[] = {    { "weof",		MTWEOF,	  do_standard, 0, FD_RDWR,   ONE_ARG,    ET_ONLINE | ET_WPROT },    { "wset",		MTWSM,	  do_standard, 0, FD_RDWR,   ONE_ARG,    ET_ONLINE | ET_WPROT },    { "eof",		MTWEOF,	  do_standard, 0, FD_RDWR, ONE_ARG,    ET_ONLINE },    { "fsf",		MTFSF,	  do_standard, 0, FD_RDONLY, ONE_ARG,    ET_ONLINE },    { "fsfm",		MTFSFM,	  do_standard, 0, FD_RDONLY, ONE_ARG,    ET_ONLINE },    { "bsf",		MTBSF,	  do_standard, 0, FD_RDONLY, ONE_ARG,    ET_ONLINE },    { "bsfm",		MTBSFM,	  do_standard, 0, FD_RDONLY, ONE_ARG,    ET_ONLINE },    { "fsr",		MTFSR,	  do_standard, 0, FD_RDONLY, ONE_ARG,    ET_ONLINE },    { "bsr",		MTBSR,	  do_standard, 0, FD_RDONLY, ONE_ARG,    ET_ONLINE },    { "fss",		MTFSS,	  do_standard, 0, FD_RDONLY, ONE_ARG,    ET_ONLINE },    { "bss",		MTBSS,	  do_standard, 0, FD_RDONLY, ONE_ARG,    ET_ONLINE },    { "rewind",		MTREW,	  do_standard, 0, FD_RDONLY, NO_ARGS,    ET_ONLINE },    { "offline",	MTOFFL,	  do_standard, 0, FD_RDONLY, NO_ARGS,    ET_ONLINE },    { "rewoffl",	MTOFFL,	  do_standard, 0, FD_RDONLY, NO_ARGS,    ET_ONLINE },    { "eject",		MTOFFL,	  do_standard, 0, FD_RDONLY, NO_ARGS,    ET_ONLINE },    { "retension",	MTRETEN,  do_standard, 0, FD_RDONLY, NO_ARGS,    ET_ONLINE },    { "eod",		MTEOM,	  do_standard, 0, FD_RDONLY, NO_ARGS,    ET_ONLINE },    { "seod",		MTEOM,	  do_standard, 0, FD_RDONLY, NO_ARGS,    ET_ONLINE },    { "seek",		MTSEEK,   do_standard, 0, FD_RDONLY, ONE_ARG,    ET_ONLINE },    { "tell",		MTTELL,	  do_tell,     0, FD_RDONLY, NO_ARGS,    ET_ONLINE },    { "status",		MTNOP,	  do_status,   0, FD_RDONLY, NO_ARGS,    0 },    { "erase",		MTERASE,  do_standard, 0, FD_RDWR,   ONE_ARG,    ET_ONLINE },    { "setblk",		MTSETBLK, do_standard, 0, FD_RDONLY, ONE_ARG,    0 },    { "lock",		MTLOCK,   do_standard, 0, FD_RDONLY, NO_ARGS,    ET_ONLINE },    { "unlock", 	MTUNLOCK, do_standard, 0, FD_RDONLY, NO_ARGS,    ET_ONLINE },    { "load",		MTLOAD,	  do_standard, 0, FD_RDONLY, ONE_ARG,    0 },    { "compression",	MTCOMPRESSION,  do_standard,  0, FD_RDONLY, ONE_ARG,    0 },    { "setdensity",	MTSETDENSITY,   do_standard,  0, FD_RDONLY, ONE_ARG,    0 },    { "drvbuffer",	MTSETDRVBUFFER, do_drvbuffer, 0, FD_RDONLY, ONE_ARG,    0 },    { "stwrthreshold",	MTSETDRVBUFFER, do_drvbuffer, MT_ST_WRITE_THRESHOLD,      FD_RDONLY, ONE_ARG, 0},    { "stoptions",	DO_BOOLEANS,    do_options,   0, FD_RDONLY,      MULTIPLE_ARGS, 0},    { "stsetoptions",   SET_BOOLEANS,   do_options,   0, FD_RDONLY,      MULTIPLE_ARGS, 0},    { "stclearoptions", CLEAR_BOOLEANS, do_options,   0, FD_RDONLY,      MULTIPLE_ARGS, 0},    { "defblksize",	MTSETDRVBUFFER, do_drvbuffer, MT_ST_DEF_BLKSIZE,      FD_RDONLY, ONE_ARG, 0},    { "defdensity",	MTSETDRVBUFFER, do_drvbuffer, MT_ST_DEF_DENSITY,      FD_RDONLY, ONE_ARG, 0},    { "defdrvbuffer",	MTSETDRVBUFFER, do_drvbuffer, MT_ST_DEF_DRVBUFFER,      FD_RDONLY, ONE_ARG, 0},    { "defcompression", MTSETDRVBUFFER, do_drvbuffer, MT_ST_DEF_COMPRESSION,      FD_RDONLY, ONE_ARG, 0},    { "stsetcln",	MTSETDRVBUFFER, do_drvbuffer, MT_ST_SET_CLN,      FD_RDONLY, ONE_ARG, 0},    { "sttimeout",	MTSETDRVBUFFER, do_drvbuffer, MT_ST_SET_TIMEOUT,      FD_RDONLY, ONE_ARG, 0},    { "stlongtimeout",	MTSETDRVBUFFER, do_drvbuffer, MT_ST_SET_LONG_TIMEOUT,      FD_RDONLY, ONE_ARG, 0},    { "densities",	0, print_densities,     0, NO_FD,     NO_ARGS,    0 },    { "setpartition",	MTSETPART, do_standard, 0, FD_RDONLY, ONE_ARG,    ET_ONLINE },    { "mkpartition",	MTMKPART,  do_standard, 0, FD_RDWR,   ONE_ARG,    ET_ONLINE },    { "partseek",	0,         do_partseek, 0, FD_RDONLY, TWO_ARGS,    ET_ONLINE },    { "asf",		0,         do_asf, MTREW,  FD_RDONLY, ONE_ARG,    ET_ONLINE },    { NULL, 0, 0, 0 }};static struct densities {    int code;    char *name;} density_tbl[] = {    {0x00, "default"},    {0x01, "NRZI (800 bpi)"},    {0x02, "PE (1600 bpi)"},    {0x03, "GCR (6250 bpi)"},    {0x04, "QIC-11"},    {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 or QIC-1000"},    {0x16, "MFM 10000 bpi"},    {0x17, "MFM 42500 bpi"},    {0x18, "TZ86"},    {0x19, "DLT 10GB"},    {0x1a, "DLT 20GB"},    {0x1b, "DLT 35GB"},    {0x1c, "QIC-385M"},    {0x1d, "QIC-410M"},    {0x1e, "QIC-1000C"},    {0x1f, "QIC-2100C"},    {0x20, "QIC-6GB"},    {0x21, "QIC-20GB"},    {0x22, "QIC-2GB"},    {0x23, "QIC-875"},    {0x24, "DDS-2"},    {0x25, "DDS-3"},    {0x26, "DDS-4 or QIC-4GB"},    {0x27, "Exabyte Mammoth"},    {0x28, "Exabyte Mammoth-2"},    {0x29, "QIC-3080MC"},    {0x30, "AIT-1 or MLR3"},    {0x31, "AIT-2"},    {0x32, "AIT-3"},    {0x33, "SLR6"},    {0x34, "SLR100"},    {0x40, "DLT1 40 GB, or Ultrium"},    {0x41, "DLT 40GB, or Ultrium2"},    {0x42, "LTO-2"},    {0x45, "QIC-3095-MC (TR-4)"},    {0x47, "TR-5"},    {0x80, "DLT 15GB uncomp. or Ecrix"},    {0x81, "DLT 15GB compressed"},    {0x82, "DLT 20GB uncompressed"},    {0x83, "DLT 20GB compressed"},    {0x84, "DLT 35GB uncompressed"},    {0x85, "DLT 35GB compressed"},    {0x86, "DLT1 40 GB uncompressed"},    {0x87, "DLT1 40 GB compressed"},    {0x88, "DLT 40GB uncompressed"},    {0x89, "DLT 40GB compressed"},    {0x8c, "EXB-8505 compressed"},    {0x90, "SDLT110 uncompr/EXB-8205 compr"},    {0x91, "SDLT110 compressed"},    {0x92, "SDLT160 uncompressed"},    {0x93, "SDLT160 comprssed"}};#define NBR_DENSITIES (sizeof(density_tbl) / sizeof(struct densities))static struct booleans {    char *name;    unsigned long bitmask;    char *expl;} boolean_tbl[] = {    {"buffer-writes", MT_ST_BUFFER_WRITES, "buffered writes"},    {"async-writes",  MT_ST_ASYNC_WRITES,  "asynchronous writes"},    {"read-ahead",    MT_ST_READ_AHEAD,    "read-ahead for fixed block size"},    {"debug",         MT_ST_DEBUGGING,     "debugging (if compiled into driver)"},    {"two-fms",       MT_ST_TWO_FM,        "write two filemarks when file closed"},    {"fast-eod",      MT_ST_FAST_MTEOM, "space directly to eod (and lose file number)"},    {"auto-lock",     MT_ST_AUTO_LOCK,     "automatically lock/unlock drive door"},    {"def-writes",    MT_ST_DEF_WRITES,    "the block size and density are for writes"},    {"can-bsr",       MT_ST_CAN_BSR,       "drive can space backwards well"},    {"no-blklimits",  MT_ST_NO_BLKLIMS,    "drive doesn't support read block limits"},    {"can-partitions",MT_ST_CAN_PARTITIONS,"drive can handle partitioned tapes"},    {"scsi2logical",  MT_ST_SCSI2LOGICAL,  "logical block addresses used with SCSI-2"},    {"no-wait",       MT_ST_NOWAIT,        "immediate mode for rewind, etc."},#ifdef MT_ST_SYSV    {"sysv",	      MT_ST_SYSV,	   "enable the SystemV semantics"},#endif    {"cleaning",      MT_ST_SET_CLN,	   "set the cleaning bit location and mask"},    {NULL, 0}};static char *tape_name;   /* The tape name for messages */	intmain(int argc, char **argv){    int mtfd, cmd_code, i, argn, len, oflags;    char *cmdstr;    cmdef_tr *comp, *comp2;    for (argn=1; argn < argc; argn++)	if (*argv[argn] == '-')	    switch (*(argv[argn] + 1)) {	    case 'f':	    case 't':		argn += 1;		if (argn >= argc) {		    usage(0);		    exit(1);		}		tape_name = argv[argn];		break;	    case 'h':		usage(1);		exit(0);		break;	    case 'v':		printf("mt-st v. %s\n", VERSION);		exit(0);		break;	    case '-':		if (*(argv[argn] + 1) == '-' &&		    *(argv[argn] + 2) == 'v') {		    printf("mt-st v. %s\n", VERSION);		    exit(0);		}		/* Fall through */	    default:		usage(0);		exit(1);	}	else	    break;    if (tape_name == NULL && (tape_name = getenv("TAPE")) == NULL)	tape_name = DEFTAPE;           if (argn >= argc ) {	usage(0);	exit(1);    }    cmdstr = argv[argn++];    len = strlen(cmdstr);    for (comp = cmds; comp->cmd_name != NULL; comp++)	if (strncmp(cmdstr, comp->cmd_name, len) == 0)	    break;    if (comp->cmd_name == NULL) {	fprintf(stderr, "mt: unknown command \"%s\"\n", cmdstr);	usage(1);	exit(1);    }    if (len != strlen(comp->cmd_name)) {	for (comp2 = comp + 1; comp2->cmd_name != NULL; comp2++)	    if (strncmp(cmdstr, comp2->cmd_name, len) == 0)		break;	if (comp2->cmd_name != NULL) {	    fprintf(stderr, "mt: ambiguous command \"%s\"\n", cmdstr);	    usage(1);	    exit(1);	}    }    if (comp->arg_cnt != MULTIPLE_ARGS && comp->arg_cnt < argc - argn) {	fprintf(stderr, "mt: too many arguments for the command '%s'.\n",		comp->cmd_name);	exit(1);    }    cmd_code = comp->cmd_code;    if (comp->cmd_fdtype != NO_FD) {	oflags = comp->cmd_fdtype == FD_RDONLY ? O_RDONLY : O_RDWR;	if ((comp->error_tests & ET_ONLINE) == 0)	    oflags |= O_NONBLOCK;	if ((mtfd = open(tape_name, oflags)) < 0) {	    perror(tape_name);	    exit(1);	}    }    else	mtfd = (-1);    if (comp->cmd_function != NULL) {	i = comp->cmd_function(mtfd, comp, argc - argn,			       (argc - argn > 0 ? argv + argn : NULL));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -