rdt.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 2,753 行 · 第 1/5 页

C
2,753
字号
#ifndef lintstatic	char	*sccsid = "@(#)rdt.c	4.1	(ULTRIX)	7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1984 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//*****************************************************************								**	RDT.C	-->	Read Diagnostic Tape			**								**	Ray Glaser	09-Oct-84				**								*****************************************************************//*	/--------------------------------------------------\		Read Diagnostic Programs from the			Diagnostic Tape		A subset of the labeled tape facility (ltf)	\--------------------------------------------------/*/#include	<stdio.h>#include	<ctype.h>#include	<sys/types.h>#include	<sys/ioctl.h>#include	<sys/mtio.h>#include	<sys/dir.h>#include	<sys/time.h>#include	<sys/stat.h>/*	Define constants for sizes of various items. */#define	NNML	100	/* Normal (ANSI) file name length.			   76 is all that seems to be used on the tape, so			   why this was def'd to 100 isn't known yet. rjg			*/#define BUFSIZE	80#define LABSIZE	80	/* Number of chctrs in an ANSI label *//*	Define constants for ? */#define CREATE		1#define WRITE		2#define EXTRACT		3#define TABLE		4#define BINARY		10#define TEXT		-10#define COUNTED		-11#define YES		1#define NO		0#define MAXBLKSIZE	20480		 /* maximum tape block length */#define MAXRECSIZE	512		/* maximum tape record length */#define MAXLEN		95		/*					 * maximum length of a file name,					 * including its pathname					 */#define MAXRECFUF	130#define MAXREC4		126#define MAXREC6		124#define RECOFF		6		/* fuf record offset */#define FIRST		1#define MIDDLE		0#define LAST		2#define ALL		3#define	FIXED		'F'		/* fixed-length tape records */#define VARIABLE	'D'		/* variable-length tape records */#define FUF		01		/* fortran unformatted file */#define DD		02		/* direct dump */#define PAD		'^'		/* padding character */#define SYSNAME		"ULTRIX"	/* system name *//* field sizes */#define	LABID	3#define	SERIAL	6#define	OWNER	14#define	FILEID	17#define	SETID	6#define	SECNO	4#define	SEQNO	4#define	GENNO	4#define	GENVSNO	2#define	CRDATE	6#define	EXDATE	6#define	BLOCKS	6#define	SYSTEM	13#define	BLKMAX	5#define	RECMAX	5#define	BYTOFFS	2#define DBYTES	4/* pad fields (reserved for future use) */#define	VRES1	20#define	VRES2	6#define	VRES3	28#define	HRES1	7#define	H2RES1	35#define	H2RES2	28#ifdef oktoc/* Volume header label */struct vol {	char	v_labid[LABID];		/* label identifier "VOL" */	char	v_labno;		/* label number */	char	v_serial[SERIAL];	/* volume serial number */	char	v_access;		/* accessibility */	char	v_res1[VRES1];		/* reserved for future use */	char	v_res2[VRES2];		/* reserved for future use */	char	v_owner[OWNER];		/* owner identifier */	char	v_res3[VRES3];		/* reserved for future use */	char	v_stdlabel;		/* standard label flag */	};/* file header/eof label */struct hdr {	char	h_labid[LABID];		/* label identifier:					 *  "HDR" or "EOF" */	char	h_labno;		/* label number */	char	h_fileid[FILEID];	/* file identifier */	char	h_setid[SETID];		/* file set identifier */	char	h_secno[SECNO];		/* file section number */	char	h_seqno[SEQNO];		/* file sequence number */	char	h_genno[GENNO];		/* generation number */	char	h_genvsno[GENVSNO];	/* generation vsn number */	char	h_crdate[CRDATE];	/* creation date */	char	h_exdate[EXDATE];	/* expiration date */	char	h_access;		/* accessibility */	char	h_blocks[BLOCKS];	/* block count */	char	h_system[SYSTEM];	/* system code */	char	h_x1[7];		/* reserved */	};/* deblocking hdr2/eof2 label */struct hd2 {	char	h2_labid[LABID];	/* label identifier:					 * "HDR" or "EOF" */	char	h2_labno;		/* label number "2" */	char	h2_datatype;		/* type identifier "D" or "F" */	char	h2_blkmax[BLKMAX];	/* maximum block size - bytes */	char	h2_recmax[RECMAX];	/* max record size - bytes */	char	h2_x1[H2RES1];		/* reserved */	char	h2_bytoffs[BYTOFFS];	/* extra stuff at the 					 * start of block  ?? */	char	h2_x2[H2RES2];		/* reserved */	};struct vol vol1;struct hdr hdr1, eof1;struct hd2 hdr2, eof2;#endif /* oktoc *//* --> In struct__filestat (below) the following members are *	used as indicated. * * f_src * ------ * When appending files, f_src is the pathname of the file as it * appears on disk.  When extracting files, it contains the * "extracted file name" (if one is specified).  It is unused when * listing files. * * f_dest * ------ * f_dest always deals with the file names (only the file identifiers) * on tape, whereas f_src only works with file names on disk. * f_dest and f_version together identify each file on tape. * * f_version * ------ * the version number of tape files.  The default value when * listing or extracting files is '*' (i.e., everything). * When appending files, the default is 1. * * f_numleft * ------ * If a number between curly braces (denoting the nth occurrence) * is appending to a file name, f_numleft is set equal to that * number.  In this case, f_numleft is decremented every time * the file appears on tape until it is equal to 0.  If no * occurrence is specified, f_numleft is set equal to -1. * The file will only be processed if f_numleft is equal to * -1 or 1. * * f_flags * ------ * f_flags is used when extracting files to indicate if the file * should be directly dumped (dd) from tape, FUF converted, or * extracted normally. */struct filestat	{	char	f_src[MAXLEN];	char	f_dest[MAXLEN];	char	f_version[MAXLEN];	int	f_numleft;	int	f_flags;	struct	filestat *f_next;	} *f_head;/* * alinkbuf is the link table when appending files. * It contains information about all head link files. */struct alinkbuf	{	ino_t	a_inum;			/* inode number */	dev_t	a_dev;			/* device */	int	a_count;		/*					 * a_count is the number of					 * links that have not yet been					 * appended to tape (if they					 * ever will).  At first,					 * a_count is equal to the					 * number of links; then it is					 * decremented each time a link					 * is appended to tape.					 */	char	a_pathname[NNML];	/* pathname of head link file */	int	a_fsecno;		/*					 * file section number of head					 * link file					 */	int	a_fseqno;		/*					 * file sequence number of head					 * link file					 */	struct	alinkbuf *a_next;	} *a_head;/* * xlinkbuf is the link table when extracting files.  It contains * information about all potential head link files that have been * extracted so far. *  xlinkbuf is important because files are only linked * if the appropriate head link file has already been extracted. * The "appropriate" head link file is determined by matching file * section numbers and matching file sequence numbers (rather than by * pathname because alternate extracted file names can be specified). */struct xlinkbuf	{	int	x_fsecno;		/*					 * file section no. of a					 * potential head link file					 */	int	x_fseqno;		/*					 * file sequence no. of a					 * potential head link file					 */	char	x_pathname[NNML];	/* extracted file name */	struct	xlinkbuf *x_next;	} *x_head;struct stat inode;FILE	*magtfp;			/* file pointer to tape device */long	block;				/* number of tape blocks extracted */static	char *progname;			/* program name for error routines */static	int numrecs = 0;		/* number of records to process */static	char label[7] = "ULTRIX";	/* tape label (volume identifier) */static	char labelbuf[(BUFSIZE*2)+2];	/* buffer for reading tape labels */int	blocksize = 2048;		/* tape blocksize */int	reclength = MAXRECSIZE;		/* record length */static	int verbose = NO;		/* verbose flag */int	func;				/* function (crxt) */char	inbuf[MAXBLKSIZE+1];		/* buffer */char	*bb;				/* fuf buffer (block) pointer */char	*rb;				/* fuf record pointer */int	nskip = 0;			/* number of files to skip with -S */int	oflag = NO;			/* -O option */int	oskip = 0;			/* number of files to skip with -O */char	posname[MAXLEN];		/* position file name (-P option) */char	posnum[MAXLEN];			/* version number of position file */int	posnth = 0;			/* nth occurrence of position file */int	poscount;			/* number of occurrences left to find */int	pos = 0;			/*					 * pos == 0 if the -P option is					 * not used.  pos == -1 if a					 * position file has been					 * specified, but has not yet 					 * been found.  pos == 1 after					 * the position file has been					 * matched on tape.					 */int	filetype = 0;			/*					 * to override normal file type					 * (FIXED or VARIABLE).					 */int	use_versnum = NO;		/*					 * indicates whether to					 * interpret version numbers					 * from input file names (-N flag).					 */int	warning_only = YES;		/* For 'rdt', we don't want to ask					 * if we should overwrite existing					 * files. ie. AUTO-OVERWRITE is					 * assumed. Formerly: program					 * prompts you after certain					 * errors if the -W flag is set					 */int	rep_misslinks = NO;		/*					 * reports undumped links					 * if the -M flag is set					 */int	toggle = NO;			/* toggles file type specifications */int	freemem = YES;			/* free memory flag */int	mstrcmp();			/* compares strings of metacharacters */int	mstrcmp_dot();			/*					 * compares strings of metacharacters					 * while distinguishing between					 * file names and file types					 */int	(*cmp)() = mstrcmp;		/* pointer to string compare routine */static	char magtdev[MAXLEN] = "/dev/rmt8";	/* default tape device name *//**************************************** * *	FILE  headr/eof  label ->  HDR1 * ****************************************//* (hdr1) ----------*/static	char	l_labelid[4];		/*[03] label identifier -					 *     "HDR" or "EOF" */static	int	l_labelno;		/*[01] label number */static	char	l_filename[18];		/*[17] file identifier */static	char	l_volid[7];		/*[06] volume identifier					 *     (tape label) 					 *     (file set identifier) */static	int	l_fsecno;		/*[04] file section number */static	int	l_fseqno;		/*[04] file sequence number */static	int	l_gen;			/*[04] generation number */static	int	l_genver;		/*[02] genration vrsn number */static	char	l_credate[6];		/*[06] creation date */static	char	l_expirdate[6];		/*[06] expiration date *//*static char	l_access[]=" ";		 *[01] accessibility */static	long	l_nblocks;		/*[06] block count *//*static char	l_sys_code[13];		 *[13] system identifier *//*static char	l_rsvd1_hdr1[7];	 *[07] reserved for future					 *     standardization *//**************************************** * *	FILE  headr/eof  label ->  HDR2 * ****************************************//* (hdr2) ----------*//*static char	l_labelid[4];		 *[03] label identifier -					 *     "HDR" or "EOF" *//*static int	l_labelno;		/*[01] label number */static	char	l_recformat;		/*[01] record format					 *	F = fixed length					 *	D = variable length					 *	S = spanned  */static	int	l_blklen;		/*[05] block length -					 *     no. chctrs/block */static	int	l_reclen;		/*[05] record length 					 * If the record format is					 * FIXED, this contains the					 * actual record length.  If					 * the record format if					 * VARIABLE, this is the					 * maximum record length					 * including the count field.					 *//*static char	l_rsvd1_hdr2[35];	 *[35] reserved for sys use *//**************************************** * *	FILE  headr/eof  label ->  HDR3 - HDR9 * ****************************************//* (hdr3 - hdr9) ---------------*//*static char	l_labelid[4];		 *[03] label identifier -					 *     "HDR" or "EOF" *//*static int	l_labelno;		/*[01] label number *//* ?? */static	char	l_systemid[14];		/*					 * identifies the system					 * that recorded the file					 */static	char spaces[LABSIZE];		/* a string of spaces */static	int fsecno;			/* fsecno of next file to be appended */static	int fseqno;			/* fseqno of next file to be appended *//*--------------------------------------------------------------------- * *  MAIN  -  checks flags and calls the appropriate subroutine to *	     begin processing the file arguments. * *-------------------------------------------------------------------*/main(argc, argv)int	argc;char	*argv[];	{	char	bsize[6];		/* blocksize from the -B option */	char	*a;			/* pointer to *argv */	int	i;	int	iflag = 0;		/*					 * the -I option.  iflag = 0 if					 * no arguments othan ther the					 * command-line arguments are					 * to be processed.  iflag = -1 					 * if the standard input is to					 * be read for more file names.					 * iflag = 1 if a file					 * containing additional file					 * arguments is given.					 */	char	inputfile[MAXLEN];	/*					 * If iflag = 1, inputfile is					 * the file containing additional					 * file arguments.  If iflag = -1,					 * inputfile[0] = '-' to indicate					 * that the user is to be					 * prompted for the other file					 * names; otherwise,  inputfile[0] = 0					 * for no prompting.					 */	FILE	*ifp;			/*					 * file pointer to inputfile					 * (if iflag = 1)					 */	for(i=0; i < LABSIZE; i++)		spaces[i] = ' ';	/* so the error routines know the name of this program */	progname = argv[0];	fprintf(stderr, "\n%s: ", progname);/*	Get the function code...  general format of the command is: * *		ltf  function  -qualifier  filename(s) * */	if(--argc > 0)		for(a = *++argv; *a != '\0'; a++)			switch(*a)				{				/*				case 'c':					func = CREATE;					break;				case 'r':					func = WRITE;					break;				*/				case 'x':					func = EXTRACT;					break;				case 't':					func = TABLE;					break;				case 'v':					verbose = YES;					break;				case '-':					errorexit("no function specified", 0, 0);					break;				default:					error("%c: unknown function", *a, 0);					usage();				}	else		usage();	argv++;/* *	Now process the qualifier(s).... **/	for(argc-- ; (a = *argv)[0] == '-' && *(a+1) != 'b' && *(a+1) != 't'		&& *(a+1) != 'u' && *(a+1) != 'd' && *(a+1) != 0 && argc > 0;		argc--, argv++)		switch(*++a)			{			char	*s1, *s2;			case 'D':				if(*++a == 0)					errorexit("no tape device specified", 0, 0);				if( strcmp(a, "800")==0)					strcpy(magtdev, "/dev/rmt0");				else if( strcmp(a, "1600")==0)					strcpy(magtdev, "/dev/rmt8");

⌨️ 快捷键说明

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