putfile.c

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

C
1,538
字号
				/*				 * 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 volume as VARIABLE format				 */				resl = res + RECOFF;				sprintf(Rb, "%04d", resl);				addrtyp(Rb, &rectype);				bytcnt -= res;				Rb += resl;				rp = Rb + RECOFF;			}/*E While irec-- */			/*			 * 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(name, Outbuf);					Rb = Bb;					rp = Rb + RECOFF;				}				res = read(fileno(fp), rp, lastbit);				if (res < 0) {			    	    PERROR "\n%s: %s%c\n\n",					Progname, EOFINM, BELL);				    return((long)(-1));				}				if (res != lastbit) {				    PERROR "%\n%s: %s%c\n\n",					Progname, WRLINM, BELL);				    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;			}/*E if bycnt > 0 */		}/*T if nbytes > 0L */		else {			if (Rb - Bb + RECOFF > Blocksize) {				bflush(name, Outbuf);				Rb = Bb;				rp = Rb + RECOFF;			}			sprintf(Rb, "%04d", RECOFF);			rectype = ALL;			addrtyp(Rb, &rectype);			Rb += RECOFF;			rp = Rb + RECOFF;		}/*F if nbytes > 0L */		res = read(fileno(fp), (char *)&nbytesl, sizeof(long));		if (res < 0) {			PERROR "\n%s: %s%c\n\n",				Progname, EOFINM, BELL);			return((long)(-1));		}		if (nbytesl != nbytes) {			PERROR "\n%s: %s%c\n\n",			    Progname, BFRCNE, BELL);			return((long)(-1));		}		}/*E while res= read ..*/	if (res < 0) {	    PERROR "\n%s: %s %s\n", Progname, CANTRD, name);	    perror(Progname);	    exit(FAIL);	}	bflush(name, Outbuf);}/*E if type == FUF *//* *	Return to the caller the number of blocks *	that were output to the volume. */return(Blocks);}/*E append()*//**//* * * Function: * *	process * * Function Description: * *	This functions writes the ANSI file header labels, *	file data, and ANSI file trailer labels to the *	output volume. * * Arguments: * *	char	*reallong;	Contains the full pathname & file name *	char	*longname;	Contains the pathname & file name *	char	*shortname;	File name only *	int	type;		Ultrix disk file type * * Return values: * *	none * * Side Effects: * *	If the function encounters an error condition during *	the output of the file, a message is output to  *	"stderr" and the function exits to system control.	 */process(reallong, longname, shortname, type)	char	*reallong;	/* Full path name_+_filename */	char	*longname;	/* Relative path name_+_filename */	char	*shortname;	/* Contains the file name only */	int	type;		/* Type of Ultrix disk file */{/* * +--> Local Variables */char	ansift;		/* Save ANSI file type character from HDR2			 * for later verbose messge output.			 */int	ch;		/* Character returned from getc to check line 			 * size for TEXT files */char	crecent;	/* Creation date century */char	*ctime();	/* Declare ctime routine */char	dummy[MAXPATHLEN+1]; /* dummy variable */int	found = 0;	/* a head link is not on tape yet */FILE	*fp;int	hlink = 0;	/* Flag set for field in HDR2 if hard link */char	interchange[18];	/* Interchange name */int	length;		/* size of complete filename */int	linkflag = NO;	/* Used to trigger output linked files 			 * message. Set to YES if the current file 			 * is linked to a file that has already 			 * been appended to the output volume.			 */int	lnkseq = 0;	/* Field in HDR2 for file sequence number that			 * a hard link points to */struct	tm *localtime();struct	ALINKBUF *lp;	/* Node for hard link files */struct	tm *ltime;int	max;		/* maximum line length */int	nlinks;		/* number of links to file */int	otype = 0;	/* If outputting sym link file, save SYMLNK 			 * file type to check in append routine *//* * Outbuf is a character array declared globally  * to ensure that it begins on a word boundary. */char	pathname[MAXPATHLEN+1]; /* path name */int	version = 1;	/* version number (1 is default) *//*------*\   Code\*------*/if (strlen(longname) >= MAXPATHLEN) {	PERROR "\n%s: %s %s%c\n\n",		Progname, FNTL, longname, BELL);	/*	 * A string that long is probably fatal...	 */	exit(FAIL);}strcpy(dummy, longname);pathname[0] = '\0';if (cp = rindex(dummy, '/')) {	*++cp = '\0';/* * ?_? NOTE:	When we  get to putting loong file names on *		the output volume.. This logic will need to *		be updated... */	if (strlen(dummy) >= MAXPATHLEN) {		PERROR "\n%s: %s %s%c\n\n",			Progname, FNTL, longname, BELL);		/*	 	* A string that long is probably fatal...	 	*/		exit(FAIL);	}	strcpy(pathname, dummy);}/* * Make the ANSI interchange file name */ strcpy(dummy,shortname);j = 0;if (!(filter_to_a(dummy,REPORT_ERRORS)))    if (Warning) {	PERROR "%s: %s %s", Progname, NONAFN, shortname);	PERROR "\n%s: %s %s", Progname, INVVID2, dummy);	j++;    }if (strlen(dummy) > 17) {    /*     * If user has requested warnings, tell user file name     * is too long for HDR1 and that it will be truncated.     */    dummy[17] = '\0';    if (Warning) {	PROMPT "\n%s: %s %s%c", Progname, FNTL, shortname, BELL);	j++;    }}if ((j > 0) && Warning)    PERROR "\n%s: %s\n\n", Progname, FILENNG);strcpy(interchange, dummy);interchange[17] = '\0';if ((fp = fopen(reallong, "r")) == NULL) {	PERROR "\n%s: %s %s%c\n\n", Progname, CANTOPEN, reallong, BELL);	perror(Progname);	exit(FAIL);}nlinks = Inode.st_nlink;/* * Get file owner's name string for HDR3. */if (getpw(Inode.st_uid,Name)) {	PERROR "\n%s: %s %d%c\n", Progname, CANTFPW, Inode.st_uid, BELL);	strcpy(Name, "          ");}/* * Owner id field in HDR3 label is maximum of 10 characters */for (j=0; j < 11 && Name[j] && Name[j] != ':'; j++)	Owner[j] = Name[j];Owner[j] = NULL;cp = ctime((long *)&Inode.st_mtime);if (cp[20] == '2' && cp [21] == '0')    crecent = '0';else    crecent = ' ';ltime = localtime((long *)&Inode.st_mtime);Blocks = 0L;max = 0;if (type == TEXT || type == SYMLNK && Nosym) {	/* 	 * If we find a really long line in the text,	 * we should output it as a spanned/segmented 	 * record rather variable length record.	 *	 * Find length of longest line.	 */	Format = 0;	ch = TRUE;	while (ch != EOF) {	    length = 0;	    while ((ch = getc(fp)) != EOF && ch != '\n')		length++;	    if (length > max)		max = length;	}/*E while (ch) */	fclose(fp);	if ((fp = fopen(reallong, "r")) == NULL) {	    PERROR "\n%s: %s %s%c\n\n", Progname, CANTOPEN, reallong, BELL);	    exit(FAIL);	}#ifdef U11	if (max + 5 > Reclength && Reclength != MAXRECSIZE) {	    PERROR "\n%s: %s %s%c\n\n", Progname, RECLTS, longname, BELL);	    return;	}/*T if (max + 5 > Reclength ... */	if (max + 5 > Reclength || max + 5 > Blocksize) {#else	if (max + 5 > Blocksize) {#endif		Format = SEGMENT;		Maxrec = max;	}/*T if (max + 5 ... */	else {		Format = VARIABLE;		Maxrec = max + 4;	}/*F if (max + 5 ... */}/*E if (type == TEXT || type == SYMLNK && Nosym) */fseek(fp, 0L, 0);/****\ *	Write  HDR1  on volume.. ****/sprintf(Dummy,	"HDR1%-17.17s%-6.6s%04d%04d%04d%02d%c%02d%03d %02d%03d %06d%-13.13s%7.7s",	interchange, Volid, Fsecno, Fseqno,	(version-1) / 100 + 1, (version-1) % 100,	crecent, ltime->tm_year, ltime->tm_yday+1, 99, 366, 0,	type == FUF ? "DECFILE11A" : IMPID, Spaces);if (Ansiv != '4') 	(void) filter_to_a(Dummy,IGNORE_ERRORS);if (write(fileno(Magtfp), Dummy, BUFSIZE) != BUFSIZE) {    PERROR "\n%s: %s %s\n", Progname, ERRWRF, longname);    perror(Magtdev);    ceot();}if (type == FUF)	max = MAXREC4;/****\ *	Write  HDR2  on volume.. ****//* * Directories always have a link count > 1 ... * So, we don't bother to enter them in the linked files list. * Also, can't hard link directories ... */if (type != DIRECT && nlinks > 1 && !Nosym) {    hlink = 1;    /*	If this file is linked to another,     *	find the ANSI file sequence number that it     *	is linked to.     */    for (lp = A_head; lp; lp = lp->a_next)	if (lp->a_inum == Inode.st_ino && lp->a_dev == Inode.st_dev) {	    found++;	    break;	}    /* If we found the file that this file is linked to in our list,     * get it's file sequence number and set linkflag.     */    if (found) {	lnkseq = lp->a_fseqno;	linkflag = YES;    }    else {	/* Else, enter info into a node for a possible reference	 */	lp = (struct ALINKBUF *) malloc(sizeof(*lp));	if (lp == NULL) {	    PERROR "\n%s: %s%c%c\n\n", Progname, NOMEM, BELL, BELL);	    exit(FAIL);	}/*T if lp == NULL */	else {	    lp->a_next = A_head;	    A_head = lp;	    lp->a_inum = Inode.st_ino;	    lp->a_dev = Inode.st_dev;	    lp->a_fsecno = Fsecno;	    lp->a_fseqno = Fseqno;	    lp->a_pathname = (char *) malloc(strlen(longname) + 1);	    if (lp == NULL) {	        PERROR "\n%s: %s%c%c\n\n", Progname, NOMEM, BELL, BELL);	        exit(FAIL);	    }/*T if lp == NULL */	    else {		strcpy(lp->a_pathname, longname);	    }	    lnkseq = 0;	}/*F if lp == NULL */    }/*F if (found) */}/*E if (type != DIRECT && nlinks > 1) *//* * Perform any special functions required for symbolic links */if (type == SYMLNK) {	otype = type;	type = TEXT;	if (!Nosym) {	    /*	     * Read the link to find out what	     * it points to.	     */	    dummy[0] = 0;	    if ((ch = readlink(reallong, dummy, MAXNAMLEN)) < 0) {		PERROR "\n%s: %s %s\n",Progname, CANTRSL, reallong);		perror(Progname);	    }	    else		dummy[ch] = '\0';	    linkflag = YES;	    /* 	     * For Symbolic links, the file data is the full  	     * path name of the file pointed to by the 	     * symbolic link. 	     */	    strcpy(Outbuf,dummy);	    max = strlen(Outbuf);	    Outbuf[max] = '\n';	    Outbuf[max+1] = '\0';#ifdef U11	    if (max + 5 > Reclength || max + 5 > Blocksize || max + 5 > MAXRECSIZE) {#else	    if (max + 5 > Blocksize) {#endif		Format = SEGMENT;		Maxrec = max;	    }	    else {		Format = VARIABLE;		Maxrec = max + 4;	    }	}/*T if (!Nosym) */ }/*T if (type == SYMLNK) *//****** * * Calculate the number of HDR / EOF  labels that will be needed * to contain the full path/file name. * */length = (strlen(longname)) -1;Lhdrl = 3;Leofl = 0;length -= 36;/* * Determine the number of HDR labels needed. */while ((length > 0) && (Lhdrl !=9)) {	length -= 76;	Lhdrl++;}/* * Determine the number of EOF labels needed. */if (length > 0) {	Leofl = 2;	while ((length >0) && (Leofl != 9)) {		length -= 76;		Leofl++;	}}/* Set the format of the record if it is not a TEXT file.  If it is, * it has already been set.  */if (type == FUF || type == COUNTED)    Format = VARIABLE;else    if (type != TEXT)	Format = FIXED;if (type == FUF)    Maxrec = max + 4;else    if (type != TEXT)#ifdef U11	Maxrec = Reclength;#else	Maxrec = Blocksize;#endifsprintf(Dummy,    "HDR2%c%05d%05d%06o%04d%04d%04d%3.3s%c%010ld%1.1d%1.1d%1.1d00%-28.28s",	Format, Blocksize, Maxrec,	Inode.st_mode & 0177777,	Inode.st_uid, Inode.st_gid,	lnkseq, Tftypes,	(type == BINARY) ? 'M' : Carriage,	(type == SYMLNK && !Nosym) ? max : Inode.st_size, 	Lhdrl, Leofl, hlink, Spaces);/* * Save ANSI file type for verbose messgae use. */

⌨️ 快捷键说明

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