rdt.c

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

C
2,753
字号
		if(ret < 0)			{			error("cannot read tape.", 0, 0);			if(oflag)				error("Incorrect tape density???", 0, 0);			return(ndone);			}		else			inbuf[ret] = 0;		/* eofok is always equal to NO with the -O option */		if(! oflag && ret)			{			labelid[0] = 0;			sscanf(inbuf, "%4s", labelid);				if(! strcmp(labelid, "EOF1"))				eofok = YES;			else if(! strcmp(labelid, "HDR1"))				eofok = NO;			}		if(! ret && ! eofok)			{			if(ndone + 1 == nwanted)				return(++ndone);			else				{				/*				 * set eofok equal to YES because EOF1				 * label will be skipped over by ioctl.				 * i.e., assume next label is EOF.				 */				if(! oflag)					eofok = YES;				ndone++;				}			}		else if(! ret && eofok)			{			/*			 * if a second eof is found (eot)			 * back up two file and stop.			 */			mt.mt_count = 2;			mt.mt_op = MTBSF;			if(ioctl(fileno(magtfp), MTIOCTOP, &mt) < 0)				errorexit("cannot backskip tape", 0, 0);			break;			}		}	mt.mt_count = 1;	mt.mt_op = MTFSF;	if(ioctl(fileno(magtfp), MTIOCTOP, &mt) < 0)		errorexit("cannot skip tape", 0, 0);	return(ndone);	}/*--------------------------------------------------------------------- * *  XTRACTF  -  extracts next LTF file to disk.  It returns the *		the character count of the extracted file or -1 if *		error.  Xtractf must return -1 upon error because a *		zero-length file will have a return value of 0. * *-------------------------------------------------------------------*/longxtractf(path, s, charcnt, name)char	*path;				/* pathname only */char	*s;				/* file name */long	charcnt;			/* character count (if applicable) */char	*name;				/* extracted filename (if different) */	{	FILE	*xfp;	char	xname[MAXLEN];	int	nbytes, count;	long	num = 0L;	char	*p;	if(*s == 0)		{/*	We are not sure if versions of a file come off the tape correctly	as of yet...rjg*/		if(use_versnum)			sprintf(xname, "%s%s.%d", path, l_filename,			(l_gen-1) * 100 + l_genver+1);		else			{			sprintf(xname, "%s%s", path, l_filename);			/* remove '.' at end of string */			remove_c(xname);			}		}	else		{		strcpy(name, s);		strcpy(xname, s);		}	for(p = xname, count = 0; xname[count]; count++)		{		if(xname[count] == '/')			p = &xname[count];		}	if(p != xname)		p++;	if(stat(xname, &inode) >= 0)		{		if(warning_only)			;#if 0	Ray Glaser and Tom Tresvik decided that since no other unix 	utility warns you (which may be alarming to field service)	about overwriting files, then  'rdt' should not either.	It may be a wrong descision, but it's ours to make and	this is our choice.			error("%s already exists.  Overwriting.", xname, 0);#endif 0		else			{			fprintf(stderr,			"%s: %s already exists.  Overwrite (y/n)? ", progname, xname);			gets(labelbuf);			if(labelbuf[0] != 'y')				{				char	dummy[256];				fprintf(stderr,				"Alternative pathname ('return' to quit processing this file)? ");				gets(dummy);				if(dummy[0] == 0)					{					skip(3);					return((long)(-1));					}				else					{					if(strlen(dummy) > MAXLEN - 1)						{						error("%s: file name too long", dummy, 0);						skip(3);						return((long)(-1));						}					else						{						strcpy(xname, dummy);						strcpy(name, xname);						}					}				}			}		}	/* Open the destination file on the disk.	*/	if((xfp = fopen(xname, "w")) == NULL)		{		checkdir(path);		if((xfp = fopen(xname, "w")) == NULL)			{			error("cannot create %s", xname, 0);			skip(3);			return((long)(-1));			}		}	/* Skip over the tape mark between the last  HDRn & the start of	   real file data.	*/	skip(1);	while((nbytes = read(fileno(magtfp), p=inbuf, l_blklen)) > 0)		{		if(l_recformat == FIXED)			{			/*			 * test if charcnt == 0L because some old tapes			 * with SYSNAME won't have a character count.			 * Foreign tapes won't have a charcnt either.			 * CHARCNT comes from  HDR4 in orginal LTF.			 */			if(charcnt == 0L)				{				char	*pp;				pp = p;				pp += nbytes;				while(*--pp == PAD);				pp++;				num += (long)(pp - p);				if(write(fileno(xfp), p, pp - p) < 0)					errorexit("cannot write on filesystem", 0, 0);				}			else				/* If charcnt > nbytes, we read less than we should				   have according to HDR4 (in org LTF).				*/				 if(charcnt >= (long)nbytes)				{				/* We get here if more bytes were read in than				   HDR4 says we should have (in org LTF).				*/				if(write(fileno(xfp), inbuf, nbytes) < 0)					errorexit("cannot write on filesystem", 0, 0);				charcnt -= (long)nbytes;				num += (long)nbytes;				}			else if(charcnt > 0L)				{				if(write(fileno(xfp), inbuf, (int)charcnt) < 0)					errorexit("cannot write on filesystem", 0, 0);				num += charcnt;				/* Set charcnt equal to -1				   so that we don't try to get any more of				   this apparent garbage from the tape. */				charcnt = (long)(-1);				}			}		else			{			while(p < &inbuf[nbytes] &&			(count = getlen(p)) >= 0)				{				if(l_recformat == VARIABLE)					{					p += 4; /* What are we skipping ? */					if(count == 0)						{						putc('\n', xfp); /* Why are we								 tacking this on ?*/						fflush(xfp);						num++;						continue;						}					}				else if(l_recformat == FUF)					{					p += 4;					if(! fufcnv(p, count, xfp))						{						error("fuf record too long.  %s not dumped", xname, 0);						skip(3);						return((long)(-1));						}					p += count;					continue;					}				else					/* l_recformat == DD */					count += 4;				if(write(fileno(xfp), p, count) < 0)					errorexit("cannot write on filesystem", 0, 0);				p += count;				num += (long)count;				if(l_recformat == VARIABLE)					{					putc('\n', xfp);					fflush(xfp);					num++;					}				}			}		}	fclose(xfp);	return(num); /* Go do next, if any, file.*/	}/*end XTRACTF*//*--------------------------------------------------------------------- * *  GETLEN  -  returns the length of the next variable-length record *		on an extract from tape. * *-------------------------------------------------------------------*/getlen(s)char	*s;	{	int val, i;	if(*s == PAD)		return(-1);	val = 0;	for(i=0; i < 4; i++)		val = 10 * val + (*s++ - '0');	return(val-4);	}static int days[2][13] =	{	{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },	{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }	};static char *months[] =	{ 0, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",	"Sep", "Oct", "Nov", "Dec" };/*--------------------------------------------------------------------- * *  DATE_YEAR  -  fills the string 'sdate' with the appropriate *		  month, day, and year. * *-------------------------------------------------------------------*/date_year(sdate, date)char	*sdate, *date;	{	int	leap, i, year, yearday;	sscanf(date, "%2d%3d", &year, &yearday);	i = 1900 + year;	leap = i%4 == 0 && i%100 != 0 || i%400 == 0;	for(i= 0; yearday > days[leap][i]; i++)		yearday -= days[leap][i];	sprintf(sdate, "%s %2d  %4d", months[i], yearday, year + 1900);	}/*--------------------------------------------------------------------- * *  DATE_TIME  -  fills the string 'sdate' with the appropriate *		  month, day, and modification time. * *-------------------------------------------------------------------*/date_time(sdate, sec)char	*sdate;long	*sec;	{	int	thisyear;	long	rettime;	struct	tm *localtime(), *ltime;	rettime = time(NULL);	ltime = localtime(&rettime);	thisyear = ltime->tm_year;	ltime = localtime(sec);	if(ltime->tm_year == thisyear)		sprintf(sdate, "%s %2d %02d:%02d", months[ltime->tm_mon + 1],		ltime->tm_mday, ltime->tm_hour, ltime->tm_min);	else		sprintf(sdate, "%s %2d  %4d", months[ltime->tm_mon + 1],		ltime->tm_mday, ltime->tm_year + 1900);	}/*--------------------------------------------------------------------- * *  CREATETP  -  initializes the tape and calls 'proc_args' to *		 process the file arguments. * *-------------------------------------------------------------------*/createtp(num, args, iflag, inputfile)int	num;			/* number of arguments to process */char	*args[];		/* array of pointers to arguments */int	iflag;			/* -I option */char	*inputfile;	{	char	line[512];		/* line from passwd file */	char	owner[14];		/* login name of owner */	int	j;	/*	 * NOTE:  createtp does not check whether you are overwriting	 * something on tape.	 */	if((magtfp = fopen(magtdev, "w")) == NULL)		errorexit("cannot write on tape.  Offline or needs write ring???", 0, 0);	/* Attempt to get the user's login name from the password file.	   NOTE: this fails... You always end up with the last name in	  the /etc/passwd file.	*/	getpw(getuid() & 0377, line);	for(j=0; j < 14 && line[j] && line[j] != ':'; j++)		owner[j] = line[j];	if(line[j] == ':')		owner[j] = 0;	upper(owner);/*	Write the VOLUME label  (VOL1) .. See  VMS note 2-6 of	VMS  MTAACP  documentation for important information.*/	sprintf(labelbuf, "VOL1%-6.6s %26.26s%-14.14s%28.28s3",	label, spaces, owner, spaces);	write(fileno(magtfp), labelbuf, LABSIZE);	fsecno = fseqno = 1;	proc_args(num, args, iflag, inputfile);	}/*end CREATETP*//*--------------------------------------------------------------------- * *  PROCESS  -  processes the given file and its label sets. *		?? Which means ? *-------------------------------------------------------------------*/process(longname, shortname, type)char	*longname;		/* contains the pathname and file name */char	*shortname;		/* file name only */int	type;			/* type of file */	{	/* dummy is a buffer for sprintf and is also a copy of longname */	static	char dummy[MAXLEN];	static	char ldummy[MAXLEN*2];	FILE	*fp;	struct	filestat fstat;	struct	alinkbuf *lp;	int	linkflag = NO;		/*					 * YES if the file is linked to					 * a file that has already been					 * appended.					 */	int	found = 0;		/* a head link is not on tape yet */	int	version = 1;		/* version number (1 is default) */	int	length;			/* length of a line of text file */	long	append();	long	charcnt = 0L;		/*					 * character count.  This is					 * just a precaution in case					 * the last character of a					 * binary file is the same as					 * the padding character.					 */	int	max;			/* maximum line length */	char	pathname[77];	char	*l, *l2;	char	line[512];		/* buffer for reading text files */	struct	tm *localtime();	struct	tm *ltime;	register int j;	pathname[0] = 0;	l = dummy;	l2 = longname;	for(j=0; (*l++ = *l2++) && j < MAXLEN; j++); /* Copy longname into dummy */	if(j >= MAXLEN)		{		error("%s: file name too long", longname, 0);		return;		}/*	Put a good string copy of the longname in filestat buffer.*/	strcpy(fstat.f_src, dummy);/*	Now, separate the base file name from the pathname+filename.*/	l = dummy;	l += strlen(dummy);	while(--l != dummy)		if(*l == '/')			break;	if(*l == '/')		{		char	*s1, *s2;		s1 = pathname;		s2 = dummy;		*l = 0;		/* The following will eventually hit the trailing zero and		   stop...		*/		for(j=0; (*s1++ = *s2++) && j < 76; j++);		if(j >= 76)			{			error("%s: pathname too long", longname, 0);			return;			}		strcat(pathname, "/");		if(! make_num(++l, fstat.f_dest, fstat.f_version))			return;		}	else		/* We come here when there is apparantly only a filename.			i.e. Not /path/name  form..		*/		{		if(! make_num(l, fstat.f_dest, fstat.f_version))			return;		}	if(strlen(fstat.f_dest) > 17)		{		error("%s: destination file name too long", longname, 0);		return;		}	/*	 * Must open shortname (rather than longname)	 * because we might be in a subdirectory.      WHY ???	 */	if((fp = fopen(shortname, "r")) == NULL)		{		error("cannot open %s", fstat.f_src, 0);		return;		}	if(stat(shortname, &inode) < 0)		{		error("cannot stat %s", fstat.f_src, 0);		return;		}	ltime = localtime(&inode.st_mtime);	block = 0L;	max = 0;	if(type == TEXT)		{		/* find length of longest line */		while(fgets(line, 512, fp) != NULL)			{			length = strlen(line);			if(line[length-1] == '\n')				length--;			if(length > max)				max = length;			if(max + 4 > reclength)				break;			}		if(max + 4 > reclength)			{			error("line too long", 0, 0);			if(warning_only)				{				if(reclength == MAXRECSIZE)					{					/* Would be nice to say why */					error("cannot append as a text file.  %s not dumped.",					fstat.f_src, 0);					error("Try appending as a BINARY file (with the -b flag).", 0, 0);					}				else					error("record length too small.  %s not dumped.",					fstat.f_src, 0);				return;				}			if(type == TEXT && reclength == MAXRECSIZE)				{				error("cannot append as a text file.  %s not dumped.",				fstat.f_src, 0);				error("Try appending as a BINARY file (with the -b flag).", 0, 0);				return;

⌨️ 快捷键说明

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