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

📄 stinit.c

📁 mt 是linux下得磁带机
💻 C
📖 第 1 页 / 共 2 页
字号:
/* This program initializes Linux SCSI tape drives using the   inquiry data from the devices and a text database.   Copyright 1996-2005 by Kai M鋕isara (email Kai.Makisara@kolumbus.fi)   Distribution of this program is allowed according to the   GNU Public Licence.   Last modified: Sun Aug 21 21:47:51 2005 by kai.makisara*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <dirent.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/sysmacros.h>#include <linux/major.h>#include <scsi/sg.h>#include "mtio.h"#ifndef FALSE#define TRUE 1#define FALSE 0#endif#define SKIP_WHITE(p) for ( ; *p == ' ' || *p == '\t'; p++)#define VERSION "0.9b"typedef struct _modepar_tr {    int defined;    int blocksize;    int density;    int buffer_writes;    int async_writes;    int read_ahead;    int two_fm;    int compression;    int auto_lock;    int fast_eod;    int can_bsr;    int no_blklimits;    int can_partitions;    int scsi2logical;    int sysv;    int defs_for_writes;} modepar_tr;typedef struct _devdef_tr {    int do_rewind;    int drive_buffering;    int timeout;    int long_timeout;    int cleaning;    int nowait;    modepar_tr modedefs[4];} devdef_tr;#define DEFMAX 2048#define LINEMAX 256#define MAX_TAPES 32#define NBR_MODES 4static int verbose = 0;/* The device directories being searched */typedef struct {    char dir[PATH_MAX];    int selective_scan;} devdir;static devdir devdirs[] = { {"/dev/scsi", 0}, {"/dev", 1}, {"", 0}};#define DEVFS_PATH    "/dev/tapes"#define DEVFS_TAPEFMT DEVFS_PATH "/tape%d"/* The partial names of the tape devices being included in the   search in selective scan */static char *tape_name_bases[] = {    "st", "nst", "rmt", "nrmt", "tape", NULL};/* The list of standard definition files being searched */static char *std_databases[] = {    "/etc/stinit.def",    NULL};	static FILE *open_database(char *base){    int i;    FILE *f;    if (base != NULL) {	if ((f = fopen(base, "r")) == NULL)	    fprintf(stderr, "stinit: Can't find SCSI tape database '%s'.\n",		    base);	return f;    }    for (i=0; std_databases[i] != NULL; i++) {	if (verbose > 1)	    fprintf(stderr, "Trying to open database '%s'.\n", std_databases[i]);	if ((f = fopen(std_databases[i], "r")) != NULL) {	    if (verbose > 1)		fprintf(stderr, "Open succeeded.\n");	    return f;	}    }    fprintf(stderr, "Can't find the tape characteristics database.\n");    return NULL;}	static char *find_string(char *s, char *target, char *buf, int buflen){    int have_arg;    char *cp, *cp2, c, *argp;    if (buf != NULL && buflen > 0)	*buf = '\0';    for ( ; *s != '\0'; ) {	SKIP_WHITE(s);	if (isalpha(*s)) {	    for (cp=s ; isalnum(*cp) || *cp == '-'; cp++)		;	    cp2 = cp;	    SKIP_WHITE(cp);	    if (*cp == '=') {		cp++;		SKIP_WHITE(cp);		if (*cp == '"') {		    cp++;		    for (cp2=cp; *cp2 != '"' && *cp2 != '\0'; cp2++)			;		}		else		    for (cp2=cp+1; isalnum(*cp2) || *cp2 == '-'; cp2++)			;		if (cp2 == '\0')		    return NULL;		have_arg = TRUE;		argp = cp;	    }	    else {		have_arg = FALSE;		argp = "1";	    }	    if (!strncmp(target, s, strlen(target))) {		c = *cp2;		*cp2 = '\0';		if (buf == NULL)		    buf = strdup(argp);		else {		    if (strlen(argp) < buflen)			strcpy(buf, argp);		    else {			strncpy(buf, argp, buflen);			buf[buflen - 1] = '\0';		    }		}		if (have_arg && c == '"')		    cp2++;		else		    *cp2 = c;		if (*cp2 != '\0')		    memmove(s, cp2, strlen(cp2) + 1);		else		    *s = '\0';		return buf;	    }	    s = cp2;	}	else	    for ( ; *s != '\0' && *s != ' ' && *s != '\t'; s++)		;    }    return NULL;}	static intnum_arg(char *t){    int nbr;    char *tt;    nbr = strtol(t, &tt, 0);    if (t != tt) {	if (*tt == 'k')	    nbr *= 1024;	else if (*tt == 'M')	    nbr *= 1024 * 1024;    }    return nbr;}	static intnext_block(FILE *dbf, char *buf, int buflen, int limiter){    int len;    char *cp, *bp;    static char lbuf[LINEMAX];    if (limiter == 0) {  /* Restart */	rewind(dbf);	lbuf[0] = '\0';	return TRUE;    }    for (len = 0 ; ; ) {	bp = buf + len;	if ((cp = strchr(lbuf, limiter)) != NULL) {	    *cp = '\0';	    strcpy(bp, lbuf);	    cp++;	    SKIP_WHITE(cp);	    memmove(lbuf, cp, strlen(cp) + 1);	    return TRUE;	}	if (len + strlen(lbuf) >= DEFMAX) {	    fprintf(stderr, "Too long definition: '%s'\n", buf);	    return FALSE;	}	cp = lbuf;	SKIP_WHITE(cp);	strcpy(bp, cp);	strcat(bp, " ");	len += strlen(cp) + 1;	if (fgets(lbuf, LINEMAX, dbf) == NULL)	    return FALSE;	if ((cp = strchr(lbuf, '#')) != NULL)	    *cp = '\0';	else	    lbuf[strlen(lbuf) - 1] = '\0';    }}	static intfind_pars(FILE *dbf, char *company, char *product, char *rev, devdef_tr *defs,	  int parse_only){    int i, mode, modes_defined, errors;    char line[LINEMAX], defstr[DEFMAX], comdef[DEFMAX];    char tmpcomp[LINEMAX], tmpprod[LINEMAX], tmprev[LINEMAX], *cp, c, *t;    char *nextdef, *curdef, *comptr;    static int call_nbr = 0;    call_nbr++;    defs->drive_buffering = (-1);    defs->timeout = (-1);    defs->long_timeout = (-1);    defs->cleaning = (-1);    defs->nowait = (-1);    for (i=0; i < NBR_MODES; i++) {	defs->modedefs[i].defined = FALSE;	defs->modedefs[i].blocksize = (-1);	defs->modedefs[i].density = (-1);	defs->modedefs[i].buffer_writes = (-1);	defs->modedefs[i].async_writes = (-1);	defs->modedefs[i].read_ahead = (-1);	defs->modedefs[i].two_fm = (-1);	defs->modedefs[i].compression = (-1);	defs->modedefs[i].auto_lock = (-1);	defs->modedefs[i].fast_eod = (-1);	defs->modedefs[i].can_bsr = (-1);	defs->modedefs[i].no_blklimits = (-1);	defs->modedefs[i].can_partitions = (-1);	defs->modedefs[i].scsi2logical = (-1);	defs->modedefs[i].sysv = (-1);	defs->modedefs[i].defs_for_writes = (-1);    }    next_block(dbf, NULL, 0, 0);    /* Find matching inquiry block */    for (errors=0 ; ; ) {	if (!next_block(dbf, defstr, DEFMAX, '{'))	    break;	find_string(defstr, "manuf", tmpcomp, LINEMAX);	find_string(defstr, "model", tmpprod, LINEMAX);	find_string(defstr, "rev", tmprev, LINEMAX);	if (!next_block(dbf, defstr, DEFMAX, '}')) {	    fprintf(stderr,		    "End of definition block not found for ('%s', '%s', '%s').\n",		    tmpcomp, tmpprod, tmprev);	    return FALSE;	}	if (!parse_only) {	    if (tmpcomp[0] != '\0' &&		strncmp(company, tmpcomp, strlen(tmpcomp)))		continue;	    if (tmpprod[0] != '\0' &&		strncmp(product, tmpprod, strlen(tmpprod)))		continue;	    if (tmprev[0] != '\0' &&		strncmp(rev, tmprev, strlen(tmprev)))		continue;	}	else if (verbose > 0)	    printf("\nParsing modes for ('%s', '%s', '%s').\n",		   tmpcomp, tmpprod, tmprev);	/* Block found, get the characteristics */	for (nextdef=defstr; *nextdef != '\0' &&		 (*nextdef != 'm' || strncmp(nextdef, "mode", 2)); nextdef++)	    ;	c = *nextdef;	*nextdef = '\0';	strcpy(comdef, defstr);	*nextdef = c;	comptr = comdef;	SKIP_WHITE(comptr);	for ( ; *nextdef != '\0'; ) {	    curdef = nextdef;	    SKIP_WHITE(curdef);	    for (nextdef++ ; *nextdef != '\0' &&		 (*nextdef != 'm' || strncmp(nextdef, "mode", 2)); nextdef++)		;	    c = *nextdef;	    *nextdef = '\0';	    mode = strtol(curdef + 4, &cp, 0) - 1;	    if (mode < 0 || mode >= NBR_MODES) {		fprintf(stderr,			"Illegal mode for ('%s', '%s', '%s'):\n'%s'\n",			tmpcomp, tmpprod, tmprev, curdef);		*nextdef = c;		errors++;		continue;	    }	    strcpy(defstr, comptr);	    strcat(defstr, cp);	    *nextdef = c;	    if (verbose > 1)		fprintf(stderr, "Mode %d definition: %s\n", mode + 1, defstr);	    if ((t = find_string(defstr, "disab", line, LINEMAX)) != NULL &&		strtol(t, NULL, 0) != 0) {		defs->modedefs[mode].defined = FALSE;		continue;	    }	    if ((t = find_string(defstr, "drive-", line, LINEMAX)) != NULL)		defs->drive_buffering = num_arg(t);	    if ((t = find_string(defstr, "timeout", line, LINEMAX)) != NULL)		defs->timeout = num_arg(t);	    if ((t = find_string(defstr, "long-time", line, LINEMAX)) != NULL)		defs->long_timeout = num_arg(t);	    if ((t = find_string(defstr, "clean", line, LINEMAX)) != NULL)		defs->cleaning = num_arg(t);	    if ((t = find_string(defstr, "no-w", line, LINEMAX)) != NULL)		defs->nowait = num_arg(t);	    defs->modedefs[mode].defined = TRUE;	    if ((t = find_string(defstr, "block", line, LINEMAX)) != NULL)		defs->modedefs[mode].blocksize = num_arg(t);	    if ((t = find_string(defstr, "dens", line, LINEMAX)) != NULL)		defs->modedefs[mode].density = num_arg(t);	    if ((t = find_string(defstr, "buff", line, LINEMAX)) != NULL)		defs->modedefs[mode].buffer_writes = num_arg(t);	    if ((t = find_string(defstr, "async", line, LINEMAX)) != NULL)		defs->modedefs[mode].async_writes = num_arg(t);	    if ((t = find_string(defstr, "read", line, LINEMAX)) != NULL)		defs->modedefs[mode].read_ahead = num_arg(t);	    if ((t = find_string(defstr, "two", line, LINEMAX)) != NULL)		defs->modedefs[mode].two_fm = num_arg(t);	    if ((t = find_string(defstr, "comp", line, LINEMAX)) != NULL)		defs->modedefs[mode].compression = num_arg(t);	    if ((t = find_string(defstr, "auto", line, LINEMAX)) != NULL)		defs->modedefs[mode].auto_lock = num_arg(t);	    if ((t = find_string(defstr, "fast", line, LINEMAX)) != NULL)		defs->modedefs[mode].fast_eod = num_arg(t);	    if ((t = find_string(defstr, "can-b", line, LINEMAX)) != NULL)		defs->modedefs[mode].can_bsr = num_arg(t);	    if ((t = find_string(defstr, "noblk", line, LINEMAX)) != NULL)		defs->modedefs[mode].no_blklimits = num_arg(t);	    if ((t = find_string(defstr, "can-p", line, LINEMAX)) != NULL)		defs->modedefs[mode].can_partitions = num_arg(t);	    if ((t = find_string(defstr, "scsi2", line, LINEMAX)) != NULL)		defs->modedefs[mode].scsi2logical = num_arg(t);	    if ((t = find_string(defstr, "sysv", line, LINEMAX)) != NULL)		defs->modedefs[mode].sysv = num_arg(t);	    if ((t = find_string(defstr, "defs-for-w", line, LINEMAX)) != NULL)		defs->modedefs[mode].defs_for_writes = num_arg(t);	    for (t=defstr; *t == ' ' || *t == '\t'; t++)		;	    if (*t != '\0' && call_nbr <= 1) {		fprintf(stderr,			"Warning: errors in definition for ('%s', '%s', '%s'):\n%s\n",			tmpcomp, tmpprod, tmprev, defstr);		errors++;	    }	}    }    if (parse_only) {	if (verbose > 0)	    printf("\n");	printf("Definition parse completed. ");	if (errors) {	    printf("Errors found!\n");	    return FALSE;	}	else {	    printf("No errors found.\n");	    return TRUE;	}    }    else {	for (i=modes_defined=0; i < NBR_MODES; i++)	    if (defs->modedefs[i].defined)		modes_defined++;	if (modes_defined == 0) {	    fprintf(stderr,		    "Warning: No modes in definition for ('%s', '%s', '%s').\n",		    tmpcomp, tmpprod, tmprev);	    errors++;	}    }    if (modes_defined)	return TRUE;    return FALSE;}static int sg_io_errcheck(struct sg_io_hdr *hdp){    int status;    status = hdp->status & 0x7e;    if ((hdp->status & 0x7e) == 0 || hdp->host_status == 0 ||	hdp->driver_status == 0)	return 0;    return EIO;}#define INQUIRY 0x12#define INQUIRY_CMDLEN  6#define SENSE_BUFF_LEN 32#define DEF_TIMEOUT 60000#ifndef SCSI_IOCTL_SEND_COMMAND#define SCSI_IOCTL_SEND_COMMAND 1#endif#define IOCTL_HEADER_LENGTH 8	static intdo_inquiry(char *tname, char *company, char *product, char *rev, int print_non_found){    int fn;    int result, *ip, i;#define BUFLEN 256    unsigned char buffer[BUFLEN], *cmd, *inqptr;    struct sg_io_hdr io_hdr;    unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY, 0, 0, 0, 200, 0};    unsigned char sense_b[SENSE_BUFF_LEN];    if ((fn = open(tname, O_RDONLY | O_NONBLOCK)) < 0) {	if (print_non_found || verbose > 0) {	    if (errno == ENXIO)

⌨️ 快捷键说明

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