rdt.c

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

C
2,753
字号
				}			/*			 * Give the user a chance to change some			 * parameters before appending the file.  BUT WHY ???			 */			fprintf(stderr, "%s: Is %s a TEXT or a BINARY file (t/b)? ", progname, fstat.f_src);			gets(line);			if(line[0] == 't')				type = TEXT;			else if(line[0] == 'b')				type = BINARY;			else if(line[0] == 'd')				type = COUNTED;			else				{				error("input must be 't', 'b' or 'd'.  %s not dumped.",				fstat.f_src, 0);				return;				}			if(type == TEXT)				{					/* WHY ? TO WHAT ?  Is there no default					size we can suggest ?  If we know to					what size, why ASK USER ?					*/				error("You MUST now increase the record length.", 0, 0);				fprintf(stderr, "%s: New record length (current value is %d)? ", progname, reclength);				gets(line);				sscanf(line, "%d", &reclength);				if(max + 4 > reclength)					{					if(reclength > MAXRECSIZE ||					line[0] <= '0' ||					line[0] > '9')						error("invalid record length (max 512).", 0, 0);					else if(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);						}					else						error("record length is still too small.  %s not dumped.", fstat.f_src, 0);					return;					}				}			}		}	else		charcnt = inode.st_size;	fseek(fp, 0L, 0);	sscanf(fstat.f_version, "%d", &version);/*	 PUT A FILE ON TAPE HERE....*/	/* HDR1 - Identify the file and the system that created the tape.	 */sprintf(dummy,	"HDR1%-17.17s%-6.6s%04d%04d%04d%02d %02d%03d %02d%03d %06d%-13.13s%7.7s",	fstat.f_dest, label, fsecno, fseqno,	(version-1) / 100 + 1, (version-1) % 100,	ltime->tm_year, ltime->tm_yday+1, 99, 366, 0,	type == FUF ? "DECFILE11A" : SYSNAME, spaces);	write(fileno(magtfp), dummy, LABSIZE);	if(type == FUF)		max = MAXREC4;/*	HDR2 - describe the record format, maximum record size, & maximum	block length of the file..*/	if(type != TEXT) /* Tell VMS NOT to give carriage return attributes */		sprintf(dummy,			 "HDR2%c%05d%05df%20.20sM%13.13s00%28.28s",		(type == TEXT || type == FUF || type == COUNTED) ? VARIABLE : FIXED, blocksize,		(type == TEXT || type == FUF) ? max + 4 : reclength, spaces, spaces,spaces);	else /* Tell VMS it is ok to give carriage return attributes */			sprintf(dummy,				 "HDR2%c%05d%05df%34.34s00%28.28s",		(type == TEXT || type == FUF || type == COUNTED) ? VARIABLE : FIXED, blocksize,		(type == TEXT || type == FUF) ? max + 4 : reclength, spaces, spaces,spaces);	write(fileno(magtfp), dummy, LABSIZE);/*	HDR3 - Stores the VAX/VMS  RMS file attributes.		For Ultrix, we put out path component here (org vsn).*/	if(type == FUF)		{		sprintf(ldummy,			 "HDR3%04x0002%010d01%044d%12.12s",		MAXREC4, 0, 0, spaces);/*		sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/		write(fileno(magtfp), ldummy, LABSIZE);		}	else		{		upper(pathname);		sprintf(ldummy,			 "HDR3%-76.76s", pathname);/*		sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/		write(fileno(magtfp), ldummy, LABSIZE);				if(inode.st_nlink > 1)			{			for(lp = a_head; lp != NULL; lp = lp->a_next)				if(lp->a_inum == inode.st_ino &&				lp->a_dev == inode.st_dev)					{					found++;					break;					}			if(found)				{				/* HDR4 - A hard link was found,				head seen,  point this file  to it.				*/	sprintf(ldummy,			 "HDR4%04o%04d%04d%04d%04d%010ld%010ld%39.39s",				inode.st_mode & 07777, inode.st_uid, inode.st_gid,				lp->a_fsecno, lp->a_fseqno, charcnt,				inode.st_mtime, spaces);/*			sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/				write(fileno(magtfp), ldummy, LABSIZE);				/* HDR5 - the head file name				*/				sprintf(ldummy,					 "HDR5%-76.76s", lp->a_pathname);/*			sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/				write(fileno(magtfp), ldummy, LABSIZE);					linkflag = YES;				lp->a_count--;				}			else				{				/* Hard link, head not seen, this must be				considered the head link ?				*/				sprintf(ldummy,					 "HDR4%04o%04d%04d%04d%04d%010ld%010ld%39.39s",				inode.st_mode & 07777, inode.st_uid, inode.st_gid,				0, 0, charcnt, inode.st_mtime, spaces);/*			sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/				write(fileno(magtfp), ldummy, LABSIZE);					lp = (struct alinkbuf *) malloc(sizeof(*lp));				if(lp == NULL)					{					if(freemem)						{						error("Out of memory.  Link information lost.", 0, 0);						freemem = NO;						}					}				else					/* Not a hard link seen.					*/					{					lp->a_next = a_head;					a_head = lp;					lp->a_inum = inode.st_ino;					lp->a_dev = inode.st_dev;					lp->a_count = inode.st_nlink - 1;					lp->a_fsecno = fsecno;					lp->a_fseqno = fseqno;					strcpy(lp->a_pathname, longname);					}				}			}		else			{			sprintf(ldummy, "HDR4%04o%04d%04d%04d%04d%010ld%010ld%39.39s",			inode.st_mode & 07777, inode.st_uid, inode.st_gid,			0, 0, charcnt, inode.st_mtime, spaces);/*			sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/			write(fileno(magtfp), ldummy, LABSIZE);			}		}	/* write an end-of-file mark on tape */	weof();/*	The label headers have been done, now write the file itself	on to the tape.*/	if((block = append(fp, type, max)) < 0L)		{		if(block == (long)(-1))			error("%s not dumped.", fstat.f_src, 0);		else			{			error("content type in question. %s not dumped.", fstat.f_src, 0);			error("Try appending as a BINARY file (with the -b flag).", 0, 0);			}		fclose(fp);		if(fseqno == 1 && fsecno == 1)			{			struct mtop	mt;			fclose(magtfp);			rew();			if((magtfp = fopen(magtdev, "w")) == NULL)				errorexit("cannot open %s for writing", magtdev, 0);			mt.mt_count = 1;			mt.mt_op = MTFSR;			if(ioctl(fileno(magtfp), MTIOCTOP, &mt) < 0)				errorexit("cannot skip 1 tape record", 0, 0);			}		else			back(1);		if(! found && lp != NULL)			{			a_head = lp->a_next;			free((char *) lp);			}		return;		}	fclose(fp);/*	Headers and file data done, now put the trailer lables on the	tape and move on to the next file.*/	weof();	sprintf(dummy,	"EOF1%-17.17s%-6.6s%04d%04d%04d%02d %02d%03d %02d%03d %06ld%-13.13s%7.7s",	fstat.f_dest, label, fsecno, fseqno,	(version-1) / 100 + 1, (version-1) % 100,	ltime->tm_year, ltime->tm_yday+1, 99, 365, block,	type == FUF ? "DECFILE11A" : SYSNAME, spaces);	write(fileno(magtfp), dummy, LABSIZE);	sprintf(dummy, "EOF2%c%05d%05d%35.35s00%28.28s",	(type == TEXT || type == FUF) ? VARIABLE : FIXED, blocksize,	(type == TEXT || type == FUF) ? max + 4 : reclength,	spaces, spaces);	write(fileno(magtfp), dummy, LABSIZE);	if(type == FUF)		{		sprintf(dummy, "EOF3%04x0002%010d01%044d%12.12s",		MAXREC4, 0, 0, spaces);		write(fileno(magtfp), dummy, LABSIZE);		}	else		{		sprintf(dummy, "EOF3%-76.76s", pathname);		write(fileno(magtfp), dummy, LABSIZE);			if(found)			{			sprintf(dummy, "EOF4%04o%04d%04d%04d%04d%010ld%010ld%39.39s",			inode.st_mode & 07777, inode.st_uid, inode.st_gid,			lp->a_fsecno, lp->a_fseqno, charcnt,			inode.st_mtime, spaces);			write(fileno(magtfp), dummy, LABSIZE);			sprintf(dummy, "EOF5%-76.76s", lp->a_pathname);			write(fileno(magtfp), dummy, LABSIZE);			}		else			{			sprintf(dummy, "EOF4%04o%04d%04d%04d%04d%010ld%010ld%39.39s",			inode.st_mode & 07777, inode.st_uid, inode.st_gid,			0, 0, charcnt, inode.st_mtime, spaces);			write(fileno(magtfp), dummy, LABSIZE);			}		}	weof();	if(verbose)		{		lower(fstat.f_dest);		lower(pathname);		if(use_versnum)			printf("a %s%s.%d", pathname, fstat.f_dest, version);		else			{			remove_c(fstat.f_dest);			printf("a %s%s", pathname, fstat.f_dest);			}		if(linkflag)			printf(" linked to %s", lp->a_pathname);		else			printf(",  %ld tape block%c", block,			block == 1L ? 0 : 's');		printf("\n");		}	fseqno++;	}/*--------------------------------------------------------------------- * *  APPEND  -  appends the given file onto tape in the appropriate *	       record and block format.  It returns the number of * 	       blocks appended. * *-------------------------------------------------------------------*/longappend(fp, type, max)FILE	*fp;int	type, max;	{	char	line[512];	int	length;	char	*p;	block = 0L;	p = inbuf;	if(type == TEXT)		{		while(fgets(line, reclength, fp) != NULL)			{			length = strlen(line);			if(line[length-1] == '\n')				line[--length] = 0;			else				return((long)(-2));/*			if(length == 0)				{				length = 2;				line[0] = line[1] = ' ';				}*/			if(length > max)				{				error("file changed size.", 0, 0);				return((long)(-1));				}			if(&p[length+4] > &inbuf[blocksize])				{				while(p < &inbuf[blocksize])					*p++ = PAD;				write(fileno(magtfp), inbuf, blocksize);				p = inbuf;				block++;				}			sprintf(p, "%04d%s", length+4, line);			p = &p[length+4];			}		if(p != inbuf)			{			while(p < &inbuf[blocksize])				*p++ = PAD;			write(fileno(magtfp), inbuf, blocksize);			block++;			}		}	else if(type == BINARY)		while((length = read(fileno(fp), p=inbuf, blocksize)) > 0)			{			if(length < blocksize)				{				p = &p[length];				while(p < &inbuf[blocksize])					*p++ = PAD;				}			write(fileno(magtfp), inbuf, blocksize);			p = inbuf;			block++;			}	else if (type == COUNTED) /* Variable length records */		{		while( fread( &length, sizeof (short), 1, fp))			{			if( length == -1 || p+length+4 > &inbuf[blocksize])				{				while( p < &inbuf[blocksize])					*p++ = PAD;				write( fileno( magtfp), inbuf, blocksize);				p = inbuf;				block++;				}			sprintf( p, "%04d", length+4);			fread( p+4, 2, (length+1)/2, fp);				/* fudge for COUNTED records always beginning				   on a word boundary in file */			p += length+4;			}				if(p != inbuf)			{			while(p < &inbuf[blocksize])				*p++ = PAD;			write(fileno(magtfp), inbuf, blocksize);			block++;			}		}	else	/* type == FUF */		{		char	rectype;		char	*rp;		long	nbytes, nbytesl, bytcnt;		int	nrec, res, irec, lastbit, resl;		/* initialize buffer pointers */		bb = inbuf;		rb = bb;		rp = rb + RECOFF;		/*		 * Loop over all records in the file.  The unformatted		 * format for f77 is as follows: each record is		 * followed and preceded by a long int which contains		 * the byte count of the record excluding the 2 long		 * integers.		 */		while((res = read(fileno(fp), &nbytes, sizeof(long))) > 0)			{			if(nbytes > 0L)				{				bytcnt = nbytes;				nrec = ((int)nbytes-1) / MAXREC6;				irec = nrec;				/*				 * if record is greater than MAXREC6,				 * then output it in chunks of MAXREC6				 * first.				 */				 while(irec--)					{					if(rb - bb + MAXRECFUF > blocksize)						{						bflush();						rb = bb;						rp = rb + RECOFF;						}					/* read record in chunks of MAXREC6 */					res = read(fileno(fp), rp, MAXREC6);					if(res < 0)						{						error("eof in middle of file", 0, 0);						return((long)(-1));						}					if(res != MAXREC6)						{						error("wrong record length in middle of file", 0, 0);						return((long)(-1));						}					/*					 * Set up the record type.  Note:					 * to get here the record must					 * be > MAXREC6 and it must be					 * split.  Thus there must be a					 * FIRST record and all other					 * records must be MIDDLE records.					 * There could be a LAST record					 * if the record was an exact					 * multiple of MAXREC6.					 */					 if(irec == nrec - 1)						rectype = FIRST;					else if(bytcnt > MAXREC6)						rectype = MIDDLE;					else						rectype = LAST;					/*					 * now output chunk of record					 * on tape as VARIABLE format					 */					resl = res + RECOFF;					sprintf(rb, "%04d", resl);					addrtyp(rb, &rectype);					bytcnt -= res;					rb += resl;					rp = rb + RECOFF;					}				/*				 * output final part (unless exact				 * multiple of MAXREC6) of record or				 * all of it if record is < MAXREC6.				 */				 if(bytcnt > 0)					{					lastbit = bytcnt;					if(rb - bb + lastbit + RECOFF > blocksize)						{						bflush();						rb = bb;						rp = rb + RECOFF;						}					res = read(fileno(fp), rp, lastbit);					if(res < 0)						{						error("eof in middle of file", 0, 0);						return((long)(-1));						}					if(res != lastbit)						{						error("wrong record length in middle of file", 0, 0);						return((long)(-1));						}					if(lastbit == nbytes)						rectype = ALL;					else						rectype = LAST;					resl = res + RECOFF;					sprintf(rb, "%04d", resl);					addrtyp(rb, &rectype);					rb += resl;					rp = rb + RECOFF;					}				}			else				{				if(rb - bb + RECOFF > blocksize)					{					bflush();					rb = b

⌨️ 快捷键说明

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