filehand.c

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

C
617
字号
#ifndef lintstatic	char	*sccsid = "@(#)filehand.c	4.1	(ULTRIX)	7/17/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1984 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.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   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.	* *									* ************************************************************************//* EMACS_MODES: c !fill tabstop=4 *//* *	filehand -- Get a handle on file operations. * * * *	This file contains a number of routines which are useful in handling *	files.  The operationd performed are defined in the filehand.h file, *	as are the return codes. */# include <stdio.h># include "filehand.h"				/* " /* Quiet cref. *//* Debugging options. */# ifdef TRACEextern FILE		*trace;# define TR(W,X,Y,Z) fprintf (trace, W, X, Y, Z)# else# define TR(W,X,Y,Z) /* W X Y Z */# endif# define READ "r"# define APP "a"# define BUFSIZE 512# define SAME 0							/* Same as strcmp. */# define BEFORE 1						/* Almost same as strcmp. */# define AFTER (-1)						/* Ditto. */# define ERROR (-1)# define OFILE1 1# define OFILE2 2# define ALLOC1 4# define ALLOC2 8# define ALLOC3 16# ifdef XALLOC/* Use this for places where xalloc and xfree are used in the code which * calls filehand routines. */USXALLOC();# endif/* *	ftrans -- Handle routine file transfer operations. */ftrans (opcode, file1, file2, area, size)int		opcode;							/* Choices are in filehand.h. */char	*file1, *file2,					/* The files to handle. */		*area;							/* Buffer area pointer. */int		size;							/* Of buffer area. */{	FILE	*fp1, *fp2;	int		retcode;	TR("Ftrans: %d (%s) (%s)\n", opcode, file1, file2);	TR("Ftrans: area=%d size=%d\n", area, size, EMPTY);	if ((opcode == RENAME || opcode == CPY) &&	  (fp2 = fopen (file2, READ)) != NULL) {		if (fclose (fp2) == ERROR)			return (RECURSE + DESTEXISTS);		return (DESTEXISTS);		}		if ((opcode == MOVE || opcode == COPYOVER)	  && (fp2 = fopen (file2, READ)) != NULL) {		if (fclose (fp2) == ERROR)			return (RECURSE + LIVEDEST);		if (unlink (file2) == ERROR)			return (LIVEDEST);		}	if ((fp1 = fopen (file1, READ)) == NULL)		return (NOSOURCE);	if ((fp2 = fopen (file2, APP)) == NULL) {		if (fclose (fp1) == ERROR)			return (RECURSE + NODEST);		return (NODEST);		}	retcode = copyrest (fp1, fp2, area, size);	if (fclose (fp1) == ERROR)		retcode = LIVESRC;	if (fclose (fp2) == ERROR)		retcode = NOCLOSE;	if (retcode != DONE)		return (retcode);	if ((opcode == MOVE || opcode == RENAME) && unlink (file1) == ERROR)		return (LIVESRC);	TR("Ftrans: normal return\n", EMPTY, EMPTY, EMPTY);	return (DONE);}copyrest (fp1, fp2, place, size)		/* Copy the rest of a file. */FILE	*fp1, *fp2;						/* Use these file pointers. */char	*place;							/* A buffer to use. */int		size;							/* Size of buffer. */{	char	*malloc (),					/* Memory allocater. */			*space;						/* Area being used. */	unsigned count;						/* Of bytes read. */	int		retcode = DONE;	TR("Copyrest: fp1=%d fp2=%d place=%d ", fp1, fp2, place);	TR("size=%d\n", size, EMPTY, EMPTY);	if (place == EMPTY) {		if (size <= 0)			size = BUFSIZE;		if ((space = malloc ((unsigned) size)) == EMPTY) {			TR("Copyrest: no space\n", EMPTY, EMPTY, EMPTY);			return (NOSPACE);			}		}	else {		if (size <= 0)			return (BADSIZE);		space = place;		}	while ((count = fread (space, sizeof (char), (unsigned) size, fp1)) >	  (unsigned) 0)		if (fwrite (space, sizeof (char), count, fp2) != count) {			retcode = COPYERROR;			break;			}	if (place == EMPTY)		free (space);	TR("Copyrest: returns %d\n", retcode, EMPTY, EMPTY);	return (retcode);}getrec (file, buffer, recsep, rectype, maxlen)FILE	*file;							/* The open file to read from. */char	buffer[],						/* The buffer to read into. */		recsep;							/* The character to break on. */int		rectype,						/* FIXED or VARYING length. */		maxlen;							/* Maximum record length. */{	int		count;						/* Of characters read. */	char	lc;	TR("Getrec: file=%d recsep=(%c) maxlen=%d", file, recsep, maxlen);	TR(" rectype=%d buffer=%d\n", rectype, buffer, EMPTY);	if (rectype == FIXED) {		TR("Getrec: FIXED record size\n", EMPTY, EMPTY, EMPTY);		count = fread (buffer, sizeof (char), (unsigned) maxlen, file);		if (count == 0)			return (FILE1EOF);		else if (count == maxlen)			return (DONE);		else			return (SHORTREC);		}	else if (rectype == VARIED) {		TR("Getrec: VARIED record size\n", EMPTY, EMPTY, EMPTY);		count = 0;		while ((lc = fgetc (file)) != EOF) {			if (lc == recsep) {				buffer[count] = NULL;				TR("Getrec: returns buffer=(%s)\n", buffer, EMPTY, EMPTY);				return (DONE);				}			else {				buffer[count++] = lc;				if (count >= maxlen)					return (BIGREC);				}			}		TR("Getrec: end of file\n", EMPTY, EMPTY, EMPTY);		buffer[count] = NULL;		return (FILE1EOF);		}	else		return (BADTYPE);				/* Unknown record type. */}rec_cmp (args, fmatch, recsep)			/* Compare a record with fmatch. */char	*args[], *fmatch[], recsep;{	int		i,							/* For looping. */			cmpstat;					/* Comparison value. */	cmpstat = SAME;	for (i = 0; fmatch[i] != EMPTY; i++) {		cmpstat = strcmp (fmatch[i], args[i]);		if (fmatch[i][0] == recsep || cmpstat == 0)			cmpstat = SAME;		else if (cmpstat > 0) {			cmpstat = BEFORE;			/* fmatch must follow args. */			/* That is, we could still match. */			break;			}		else {			cmpstat = AFTER;			break;						/* The for loop. */			}		}	TR("Rec_cmp: returns %d\n", cmpstat, EMPTY, EMPTY);	return (cmpstat);}argchop (s, fldsep, sargs)				/* Seperate s into its fields. */char	*s,								/* The string to seperate. */		fldsep,							/* Seperates the fields. */		**sargs;						/* Pointers to the fields. */{	int		i = 0,						/* For looping. */			subs = 0;					/* Counter of fields. */	TR("Argchop: s=(%s) fldsep=(%c) sargs=%d\n", s, fldsep, sargs);	while (s[i] == fldsep || (fldsep == WHITE && (s[i] == ' '	  || s[i] == '\t')))		s[i++] = NULL;					/* Skip initial blank fields. */	while (s[i] != NULL) {		if (s[i] == fldsep || (fldsep == WHITE && (s[i] == ' '		  || s[i] == '\t')))			s[i] = NULL;				/* Insert a string terminater. */		else if ((i > 0 && s[i - 1] == NULL) || i == 0)			sargs[subs++] = &s[i];		/* An argument begins here. */		i++;		}	sargs[subs] = EMPTY;# ifdef TRACE							/* Echo the fields. */	for (i = 0; sargs[i] != EMPTY; i++)		TR(".. %d (%s)\n", i, sargs[i], EMPTY);# endif	TR("Argchop: normal return\n", EMPTY, EMPTY, EMPTY);	return (DONE);}/* *	sweep -- One shot file modification.  Execute the request and exit. */sweep (opcode, file1, file2, recsep, fldsep, maxlen, fmatch, usrbuf, usrmatch,  chop, compare)int		opcode;							/* The operation to perform. */char	*file1,							/* The search/source file. */		*file2,							/* The scratch file.  (Required.) */		recsep,							/* Record seperator. */		fldsep;							/* Field seperator. */int		maxlen;							/* Maximum length of record. */char	*fmatch[],						/* Fields to match. */		*usrbuf,						/* User's copy of matching record. */		*usrmatch[];					/* Pointers to arguments. */int		(*chop)(),						/* Routine to seperate the fields. */		(*compare)();					/* Routine to compare records. */{	char	**arg,						/* Pointers to the fields. */			*realrec,					/* A copy of what was actually read. */			*hackrec;					/* A place to keep the fields. */	int		cmpstat,					/* Comparison status. */			retcode,					/* Return code. */			action = 0,					/* Record of what we have done. */			rectype,					/* FIXED or VARIED record size. */			i, j;						/* Looping variable. */	FILE	*fp1, *fp2;					/* Pointers to file1 and file2. */	char	*malloc (),					/* Memory allocation. */			*strncpy ();				/* String copy in lPW. */	TR("Sweep: opcode=%d file1=(%s) file2=(%s)\n", opcode, file1, file2);	TR(".. recsep=(%c) fldsep=(%c) maxlen=%d ", recsep, fldsep, maxlen);	TR("usrbuf=%d usrmatch=%d chop=%d\n", usrbuf, usrmatch, chop);	TR(".. usrbuf=(%s) compare=%d\n", usrbuf, compare, EMPTY);#ifdef TRACE	TR(".. fmatch ..\n", EMPTY, EMPTY, EMPTY);

⌨️ 快捷键说明

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