putfile.c

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

C
1,538
字号
#ifndef lintstatic	char	*sccsid = "@(#)putfile.c	4.1	(ULTRIX)	7/17/90";#endif	lint/**************************************************************** *								* *			Copyright (c) 1985 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.					* *								* *   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.					* *								* ****************************************************************//**//* * *	File name: * *		putfile.c * *	Source file description: * *		This file contains the logic to put  *		individual files on an output volume for *		the Labeled Tape Facility (LTF).	 *		 * *	Functions: * *		bflush()	Flushes Fortran Unformatted File *				record buffer data to output *				volume. * *		addrtyp()	?_? Used during Fortran Formatted *				File output record processing. * *		append()	Appends (writes) the current *				file to the output volume. * *		process()	The function that actually *				writes the ANSI file header *				and ANSI file trailer *				records on the output volume. * *		putfile()	Determines the "type" of file *				being put on the output volume *				and calls function "process" to *				cause the file to be output. * *	Usage: * *		n/a * *	Compile: * *	    cc -O -c putfile.c		<- For Ultrix-32/32m * *	    cc CFLAGS=-DU11-O putfile.c	<- For Ultrix-11 * * *	Modification history: *	~~~~~~~~~~~~~~~~~~~~ * *	revision			comments *	--------	----------------------------------------------- *	  01.0		2-May-85	Ray Glaser *			Create original version.	 * *	  01.1		10-Sep-85	Suzanne Logcher *			Add logic to detect current century * *	  01.2		24-Sep-85	Suzanne Logcher *			Add logic to treat directory and subdirectory *			entries using ../ or ./ as relative pathnames * *	  01.3		31-Oct-85	Suzanne Logcher *			Add logic to create segmented files * *	  01.4		25-Mar-87	Suzanne Logcher *			Removed the declaration of Inbuf from *			process() because it was not on a word *			boundary needed for some tape drives. *			Now is called Outbuf and is global. *//* * +--> Local Includes */#include	"ltfdefs.h"char	*rindex();/**//* * * Function: * *	bflush * * Function Description: * *	Flushes (writes to output volume) the Fortran *	Unformatted File  record buffer. * * Arguments: * *	char	*name	filename used when error in write *	char	*Outbuf	file writing buffer * * Return values: * *	none * * Side Effects: * *	Data is written to the output volume from the *	and the blocks written count is updated. */bflush(name, Outbuf)	char	*name;	/* filename */	char	*Outbuf; /* File writing buffer */{if (Rb - Bb > 0) {	while (Rb < Bb + Blocksize)		*Rb++ = PAD;	if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) {	    PERROR "\n%s: %s %s\n", Progname, ERRWRF, name);	    perror(Magtdev);	    ceot();	}	Blocks++;}}/*E bflush() *//**//* * * Function: * *	addrtyp * * Function Description: * *	Used during output to a volume for Fortran *	Unformatted File proccessing   ?_? * * Arguments: * *	char	*inch	?_? *	char	*typ	?_? * * * Return values: * *	none * * Side Effects: * *	not known at this time	 */addrtyp(inch, typ)	char	*inch;	char	*typ;{inch[4] = typ[0];inch[5] = typ[1];}/*E addrtyp() *//**//* * * Function: * *	append * * Function Description: * *	Appends (writes) the given file to the output volume. * * Arguments: * *	char	*name	filename *	FILE	*fp	Pointer to file to output *	int	max	Maximum line length	 *	int	type	Type of ANSI tape file being output *	int	tftype	True file type of file being output *	char	*Outbuf	File writing buffer * * Return values: * *	Returns a LONG count of number of blocks output. * *	Returns -1  and  -2  as error indicators. * * Side Effects: * *	 */long append(name, fp, type, tftype, max, Outbuf)	char	*name;	/* filename */	FILE	*fp;	int	type, tftype, max;	char	*Outbuf;	/* File writing buffer */{/* * +--> Local Variables */int	done;		/* Boolean used for segmented records */int	fillbuf;	/* Integer of amount of data to read to fill 			 * line buffer to Blocksize */char	*index();	/* subroutine to find first char in string */int	length;		/* Length of line */char	line[MAXBLKWRT+1];	/* Line read in from file to output */int	midway;		/* Boolean used for segmented records */int	notfini;	/* Boolean used for TEXT loop */char	*p;		/* Pointer to the line input buffer */char	*q;		/* Pointer to the line input buffer */int	used = 0;	/* Number of characters used in Buffer for 			 * segmented records *//*------*\   Code\*------*/Blocks = 0L;p = Outbuf;/*------*\	TEXT FILE\*------*/if (type == TEXT) {	    notfini = TRUE;	    midway = FALSE;	    q = line;	    fillbuf = Blocksize;	    while (notfini != EOF) {		if (tftype != SYMLNK || Nosym) {		    if ((i = read(fileno(fp), q, fillbuf)) <= 0)			if (i < 0) {			    PERROR "\n%s: %s %s\n", Progname, CANTRD, name);			    perror(Progname);			    exit(FAIL);			}			else			    break;		    q[i] = '\0';		}		else		    strcpy(line, Outbuf);		q = line;		done = FALSE;		while (done == FALSE) {		    if (cp = index(q, '\n'))			*cp = '\0';		    else			if (Format == VARIABLE)			    break;		    length = strlen(q);		    if (length > max)			return((long)(-1));		    if (Format == VARIABLE) {			if (&p[length+4] > &Outbuf[Blocksize]) {		    	    while (p < &Outbuf[Blocksize])				*p++ = PAD;			    if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) {	    			PERROR "\n%s: %s %s\n", Progname, ERRWRF, name);	    			perror(Magtdev);	    			ceot();			    }		    	    p = Outbuf;		    	    Blocks++;	        	}			sprintf(p, "%04d%s", length+4, q);			p = &p[length+4];			q = ++cp;		    }/*T if (Format == VARIABLE) */		    else {			if (&p[length+5] <= &Outbuf[Blocksize]) {			    if (cp) {				if (midway == FALSE)				    sprintf(p, "%01d%04d%s", 0, length+5, q);				else {				    sprintf(p, "%01d%04d%s", 3, length+5, q);				    midway = FALSE;				}/*F if (midway == FALSE) */				used += length + 5;				p = &p[length+5];				q = ++cp;			    }/*T if (cp) */			    else {				strcpy(line, q);				q = &line[length];				fillbuf = Blocksize - length;				done = TRUE;			    }/*F if (cp) */			}/* T if (&p[length+5] <= ... */			else {			    if (used + 5 < Blocksize) {				if (midway == FALSE) {				    sprintf(p, "%01d%04d%s", 1, Blocksize-used, q);				    midway = TRUE;				}/*T if (midway == FALSE) */				else				    sprintf(p, "%01d%04d%s", 2, Blocksize-used, q);				q = &q[Blocksize-used-5];				length -= Blocksize-used-5;			    }/* T if (used + 5 < Blocksize) */ 			    else				while (p < &Outbuf[Blocksize])				    *p++ = PAD;			    used = 0;			    if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) {	    			PERROR "\n%s: %s %s\n", Progname, ERRWRF, name);	    			perror(Magtdev);	    			ceot();			    }			    p = Outbuf;			    Blocks++;			    if (cp)				q[length] = '\n';			    if (strlen(q) == 0) {				q = line;				fillbuf = Blocksize;				done = TRUE;			    }		        }/*F if (&p[length+5] <= ... */		    }/*F if (Format == VARIABLE) */	    	}/*E while (done == FALSE) */		if (tftype == SYMLNK && !Nosym)		    notfini = EOF;		if (Format == VARIABLE) {		    length = strlen(q);		    strcpy(line, q);		    q = &line[length];		    fillbuf = Blocksize - length;		}	    }/*E while (notfini != EOF */	    if (p != Outbuf) {		while (p < &Outbuf[Blocksize])	    	    *p++ = PAD;		if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) {	    	    PERROR "\n%s: %s %s\n", Progname, ERRWRF, name);	    	    perror(Magtdev);	    	    ceot();		}		Blocks++;	    }}/*T if type == TEXT *//*------*\	BINARY FILE\*------*/if (type == BINARY) {	while ((length = read(fileno(fp), p=Outbuf, Blocksize)) > 0) {		if (length < Blocksize) {			p = &p[length];			while (p < &Outbuf[Blocksize])				*p++ = PAD;		}		if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) {	    	    PERROR "\n%s: %s %s\n", Progname, ERRWRF, name);	    	    perror(Magtdev);	    	    ceot();		}		p = Outbuf;		Blocks++;    	}/*E while length = read ..*/	if (length < 0) {	    PERROR "\n%s: %s %s\n", Progname, CANTRD, name);	    perror(Progname);	    exit(FAIL);	}}/*T if (type == BINARY) *//*------*\	COUNTED RECORD FILE \*------*/if (type == COUNTED) {    while ( fread((char *)&length, sizeof (short), 1, fp)) {	if ( length == -1 || p+length+4 > &Outbuf[Blocksize]) {		while ( p < &Outbuf[Blocksize])			*p++ = PAD;		if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) {	    	    PERROR "\n%s: %s %s\n", Progname, ERRWRF, name);	    	    perror(Magtdev);	    	    ceot();		}		p = Outbuf;		Blocks++;	}/*E if length == -1 ..*/	sprintf( p, "%04d", length+4);	if (!fread( p+4, 2, (length+1)/2, fp)) {    	    PERROR "\n%s: %s %s\n", Progname, CANTRD, name);    	    perror(Magtdev);	    exit(FAIL);	}	/*	 * Fudge for COUNTED records always beginning	 * on a word boundary in file	 */	p += length+4;    }/*E while fread ..*/		    if (p != Outbuf) {	while (p < &Outbuf[Blocksize])		*p++ = PAD;	if (write(fileno(Magtfp), Outbuf, Blocksize) != Blocksize) {    	    PERROR "\n%s: %s %s\n", Progname, ERRWRF, name);    	    perror(Magtdev);    	    ceot();	}	Blocks++;    }/*E if p != Outbuf */}/*T if type == counted *//*------*\	FORTRAN UNFORMATTED FILE\*------*/if (type == FUF) {	/*	 * +--> Local Variables	 */	long	bytcnt;	int	irec;	int	lastbit;	int	nrec;	long	nbytes, nbytesl;	char	rectype;	int	res, resl;	char	*rp;	/*	 * Initialize buffer pointers	 */	Bb = Outbuf;	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), (char *)&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(name, Outbuf);					Rb = Bb;					rp = Rb + RECOFF;				}				/*			 	* Read record in chunks of MAXREC6			 	*/				res = read(fileno(fp), rp, MAXREC6);				if (res < 0) {			    	PERROR "\n%s: %s%c\n\n",					Progname, EOFINM, BELL);			    	return((long)(-1));				}				if (res != MAXREC6) {				    PERROR "%\n%s: %s%c\n\n",					Progname, WRLINM, BELL);				return((long)(-1));				}

⌨️ 快捷键说明

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