rdt.c

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

C
2,753
字号
				struct mtop	mt;				mt.mt_count = 1;				mt.mt_op = MTBSF;				if(ioctl(fileno(magtfp), MTIOCTOP, &mt) < 0)					errorexit("cannot backskip tape", 0, 0);				error("cannot read HDR3 from tape", 0, 0);				}			else				{#ifdef DEBUG	fprintf(stdout,"\n_tp: DECFILE11A seen_\n"); pr_label();#endif				sscanf(labelbuf, "%3s%1d%4x%4x", l_labelid,				&l_labelno, &num1, &num2);				if(strcmp(l_labelid, "HDR") || l_labelno != 3)					{					errorexit("%s%d: illegal label format (HDR3)",					l_labelid, l_labelno);					}				if(num1 == MAXREC4 && num2 == 2)					l_recformat = FUF;				}			}		/* Expanded version number (combines l_gen and l_genver)		*/		verno_exp = (l_gen-1) * 100 + l_genver + 1;		itoa(verno_exp, verno_exp_a);		sprintf(name, "%s%s", pathname, l_filename);/*   The next question says:  We have been told to position the tape   but have not (as yet) reached the position.*/		if(pos == -1)			{			/* for additional interpretation */			char	posname2[MAXLEN];			posname2[0] = 0;			if(! use_versnum)				{				int	length;					length = strlen(posname);				/*				 * skip '.' at end of posname.  second dot				 * must be 2, 3, or 4 places behind ending dot.				 * e.g., ansi.exe. , ansi.ex. , ansi.c.				 */				for(i = length - 2; i >= length - 5; i--)					{					if(posname[i] == '.')						{						if(i == length - 2)							break;						strcpy(posname2, posname);						posname2[length-1] = 0;						break;						}					if(posname[i] < 'a' ||					posname[i] > 'z')						break;					}				}			if(! (*cmp)(name, posname) ||			(! use_versnum && ! (*cmp)(name, posname2)))				{				/* true if (! use_versnum) or				 * if (use_versnum && mstrcmp()).				 */				if(! use_versnum || ! mstrcmp(verno_exp_a, posnum))					{					if(poscount == -1)						pos = 1;					else if(poscount == 1)						{						poscount--;						pos = 1;						}					else if(poscount)						{						poscount--;						skip(3);						continue;						}					}				else					{					skip(3);					continue;					}				}			else				{				skip(3);				continue;				}			}		/*		 * numrecs equals 0 if no file arguments are specified.		 * Thus the entire tape must be processed.		 */		if(! numrecs ||		((fstat = lookup(name, verno_exp_a)) != NULL))			/*			The last comment seems to be saying:  Do this is			if we are extracting ALL files; -or- The user wants			the one we are positioned at.			*/			{			if(use_versnum)				sprintf(name, "%s%s.%d", pathname,				l_filename, verno_exp);			else				/* remove '.' at end of string */				remove_c(name);			if(func == TABLE)				skip(2);			else /* Does the file have links ? */			     if(lnk_fsecno != 0 && lnk_fseqno != 0)				{				int	found = 0;				for(lp = x_head; lp != NULL; lp = lp->x_next)					{					/* Look thru our links.. */					if(lp->x_fsecno == lnk_fsecno &&					lp->x_fseqno == lnk_fseqno)						{						found++;						break;						}					}				if(found)					{					char	path[MAXLEN];					char	*p;					if(stat(name, &inode) >= 0) /* ck for any error rtn */						{						if(warning_only)							error("%s already exists.  Overwriting and linking.", name, 0);						else							{							fprintf(stderr,							"%s: %s already exists.  Overwrite and link (y/n)? ", progname, name);							gets(labelbuf);							if(labelbuf[0] != 'y')								{								skip(3);								continue;								}							}						}					else						{						strcpy(path, name);						p = path;						p += strlen(path);						while(--p != path)							{							if(*p == '/')								break;							}						if(*p == '/')							{							*++p = 0;							checkdir(path);							}						}					unlink(name);					if(link(lp->x_pathname, name) < 0)						error("cannot link %s to %s",						lp->x_pathname, name);					else						{						linkflag = YES;						skip(2);						}					}				else if(freemem)					error("cannot link %s.  Head link was not extracted.", name, 0);				}			else				{				lp = (struct xlinkbuf *) malloc(sizeof(*lp));				if(lp == NULL)					{					if(freemem)						{						error("Out of memory.  Link information lost", 0, 0);						freemem = NO;						}					}				else					{					/* Add this into the list of "link"					   files in case we are one or are					   pointed to by someone.					 */					lp->x_next = x_head;					x_head = lp;					lp->x_fsecno = l_fsecno;					lp->x_fseqno = l_fseqno;					strcpy(lp->x_pathname, name);					}				}			xname[0] = 0;	/* The following test basically says:		Did the user want to override what we think the disk file		file format should be ?	*/			if(func == EXTRACT && numrecs && fstat->f_flags)				{				if(fstat->f_flags & FUF && fstat->f_flags & DD)					error("your -u request has precedence over the -d option.", 0, 0);				if(fstat->f_flags & FUF)					{					if(l_recformat == VARIABLE)						l_recformat = FUF;					else						error("the -u option does not apply when extracting binary files", 0, 0);					}				if(fstat->f_flags & DD)					{					if(l_recformat == VARIABLE)						l_recformat = DD;					else						error("the -d option does not apply when extracting binary files", 0, 0);					}				}			/* This file is not a link. */			if(func == EXTRACT && ! linkflag)				{				/* Go extract a real file from the tape.				*/				ret = xtractf(pathname,				! numrecs ? "" : fstat->f_src,				charcnt, xname);				/*				  Did the extract go ok and is this an				  Ultrix tape ?				*/				if(ret >= 0L && ! strcmp(l_systemid, SYSNAME))				 /* /\--> a ret of -1 === an error */					{					char	temp[MAXLEN];					/*					The following says: Did the user give					us a name to use for this file on the					disk, or should we use the name of					the file as we interpreted it from					the tape ?					*/					strcpy(temp, xname[0] != 0 ? xname : name);					chmod(temp, mode);					chown(temp, uid);					/* no chgrp routine					chgrp(temp, gid);					*/					if(modtime > 0L)						{						time_t	timep[2];						timep[0] = time(NULL);						timep[1] = modtime;						utime(temp, timep);						}					}				/*				Ask the question: If this is "NOT" a				-link- file ?				*/				if((lnk_fsecno == 0 || lnk_fseqno == 0)				&& lp != NULL)					{				  /* If error on extract & we have something				     in our extract list - then do the				     following.				  */					if(ret < 0L)						{						/* Remove this file name from						 our list of extracted files.						 (used for links) */						x_head = lp->x_next;						free((char*)lp);						continue;						}					else					     /* Else, if the user specified an					     extract name, put that name in our					     list instead of the name it has on tape.					     */					     if(xname[0] != 0)	 strcpy(lp->x_pathname, xname);					}				/* stop processing any files with				 * ret < 0L that haven't been caught				 * before this.  e.g., non-head link				 * files that were not extracted.				 */				if(ret < 0L)					continue;				}			if(read(fileno(magtfp), labelbuf, LABSIZE) < 0)				errorexit("cannot read EOF1 from tape", 0, 0);			sscanf(labelbuf, "%3s%1d%*50c%6ld", l_labelid,			&l_labelno, &l_nblocks);#ifdef DEBUG	pr_label();#endif			if(strcmp(l_labelid, "EOF") || l_labelno != 1)				{				errorexit("%s%d: illegal label format (EOF1)",				l_labelid, l_labelno);				}			/* The following constant of 1 will fail when we implement			   all of  LTF	functionality. */			/* skip rest of EOF label set */			skip(1);			if(func == TABLE)				{				if(verbose)					{					sprintf(cat_misc, "(%d,%d)", l_fseqno, l_fsecno);					printf("%-7s", cat_misc);					if(strcmp(l_systemid, SYSNAME))						printf("---------   -/-   ");					else						{						expand_mode(mode);						printf("%4d/%-4d", uid, gid);						}					if(modtime > 0L)						date_time(sdate, &modtime);					else						date_year(sdate, l_credate);					printf("%12s", sdate);					sprintf(cat_misc, "%ld(%d)%c", l_nblocks,					l_blklen, l_recformat == 'D' ? 't' : 'b');					printf("%11s", cat_misc);					if(strlen(name) > 30)						printf("\n       %s", name);					else						printf(" %s", name);					}				else					printf("%s", name);				if(lnk_fsecno != 0 && lnk_fseqno != 0)					printf("%slinked to %s\n",					verbose ? "\n       " : " ", lnk_name);				else					printf("\n");				}			else if(verbose)				{				if(linkflag)					printf("x %s linked to %s\n", name,					lp->x_pathname);				else					{					printf("x %s,  %ld byte%c, %ld %d-byte tape block%c",					name, ret, ret == 1 ? 0 : 's',					l_nblocks, l_blklen,					l_nblocks == 1L ? 0 : 's');					if(l_recformat == FUF)						printf(" (fuf)\n");					else if(l_recformat == DD)						printf(" (dd)\n");					else						printf("\n");					if(xname[0] != 0)						printf("  > %s\n", xname);if ((func == EXTRACT)) {	char *sp;	int wildc;	wildc = NO;	sp = fstat->f_dest;	while (*sp != '\n') {		if ((*sp == '*') || (*sp == '?')) {			wildc = YES;			break;		}		sp++;	}	if ((!wildc) && (numrecs)) {		strcpy(fstat->f_src,"1extracted1");		strcpy(fstat->f_dest,"1extracted1");		fstat->f_numleft =0;		numrecs--;		if (!numrecs) exit(0);	}}					}				}			}		else			skip(3);		}/*E for ;;..*/	}/*end SCANTAPE*//*--------------------------------------------------------------------- * *  LOOKUP  -  looks up the given LTF entry among user-input *	       file arguments. * *-------------------------------------------------------------------*/struct filestat *lookup(name, gen)char	*name;			/* file name (and file type) */char	*gen;			/* version number */	{	struct	filestat *fstat;	char	*d, *n;	char	dest2[MAXLEN];		 /* for additional interpretation */	for(fstat = f_head; fstat != NULL; fstat = fstat->f_next)		{		if(! fstat->f_numleft)			continue;		dest2[0] = 0;		if(! use_versnum)			{			int	i, length;			length = strlen(fstat->f_dest);			/*			 * skip '.' at end of dest.  second dot			 * must be 2, 3, or 4 places behind ending dot.			 * e.g., ansi.exe. , ansi.ex. , ansi.c.			 */			for(i = length - 2; i >= length - 5; i--)				{				if(fstat->f_dest[i] == '.')					{					if(i == length - 2)						break;					strcpy(dest2, fstat->f_dest);					dest2[length-1] = 0;					break;					}				}			}		if(! (*cmp)(name, fstat->f_dest) ||			(! use_versnum && ! (*cmp)(name, dest2)))			{			if(! use_versnum || ! mstrcmp(gen, fstat->f_version))				{				if(fstat->f_numleft == -1)					return(fstat);				if(fstat->f_numleft == 1)					{					fstat->f_numleft--;					return(fstat);					}				/* decrement if f_numleft > 1 */				if(fstat->f_numleft)					fstat->f_numleft--;				return(NULL);				}			}		/*		 * check if the LTF entry is a file		 * (recursively) under a requested directory.		 */		n = name;		d = fstat->f_dest;		while(*n == *d)			{			n++;			d++;			}		if(*d == '.' && *(d+1) == 0 && (*(d-1) == '/' || *n == '/'))			return(fstat);		}	return(NULL);	}/*--------------------------------------------------------------------- * *  SKIP  -  skips 'nwanted' number of tape files.  It returns the *	     number of files actually skipped. * *-------------------------------------------------------------------*/skip(nwanted)int	nwanted;	{	int	ndone;	struct	mtop mt;	int	ret;	char	labelid[5];	int	eofok = NO;		/*					 * determines when an eof					 * indicates an eot.  A					 * zero-length LTF file					 * will cause a premature eot					 * unless we use 'eofok'.					 */	mt.mt_count = 1;	mt.mt_op = MTFSF;	for(ndone=1; ndone != nwanted; ndone++)		{		if(ioctl(fileno(magtfp), MTIOCTOP, &mt) < 0)			errorexit("cannot skip tape", 0, 0);		inbuf[0] = 0;		ret = read(fileno(magtfp), inbuf, sizeof(inbuf));

⌨️ 快捷键说明

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