⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 invcutter.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
/*	invcutter.c -- *		generate full inventory from MI records and filesystem data. * *			Copyright (c) 1985, 1989 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. * *	Overall algorithm: *		reads master inventory records (MiRecT) from stdin. *		with each record, gather all file statistics and fill *		out an inventory record (InvRecT). For files with *		link counts greater than 1, call LinkResolve() to *		resolve hard links. * *	Mods: *		2.0,1	ccb	14-jan-1987 *		Unify directory type to compensate for tar change leaving *			empty dirs off tape. * *	001	14-feb-1989	ccb *		25 months later.... *		Clean Up to use underlying routines done for update install. *		Guarantee perfect sort order for use by update routines. * *	002	29-apr-1989	ccb *		lint. * *	003	14-jun-1989	ccb *		remove a few minor system dependencies *	004	24-jul-1989	ccb *		Include <sys/dir.h> for setld.h *		More Lint. *		Minor changes for libsetld.a conformance*/#ifndef lintstatic char *sccsid = "@(#)invcutter.c	4.1	(ULTRIX)	7/2/90";#endif lint#include	<sys/param.h>#include	<sys/stat.h>#include	<sys/dir.h>#include	<errno.h>#include	<string.h>#include	<stdio.h>#include	"setld.h"extern char	*sys_errlist[];	/* errno(2) */extern int	errno;		/* errno(2) */extern char	*optarg;	/* getopt(3) */extern int	optind, opterr;	/* getopt(3) */extern void	exit();		/* exit(3) *//*	Command Flags*/#define	VERSION	0x0001#define	MNTPATH	0x0002#define	DEBUGON	0x0004#define	Usage()	(void) fprintf(stderr,"Usage: %s [-v vcode][-f mntpath]\n",prog)#define	DEBUG()	(flags & DEBUGON)typedef struct ResQT {	struct ResQT	*rq_next;	char		rq_path[MAXPATHLEN+1];	dev_t		rq_dev;	ino_t		rq_ino;	short		rq_nlink;} ResQT;static ResQT	*LinkSearch();static ResQT	*ResQCreate();static ResQT	*ResQNew();unsigned	flags;		/* program command flags */char 		*prog;		/* program name */char		*version;	/* version code */ResQT		*links = NULL;	/* hard link resolution queue */main(argc,argv)int argc;char *argv[];{	InvT		*i;		/* output inventory */	InvRecT		*ip;		/* record under contruction */	PathT		lastpath;	/* last path seen */	MiT		*mi;		/* input master inventory */	MiRecT		*mip;		/* pointer to current record */	int		opt;		/* for use w/getopt() */	char		*path;		/* tmp path pointer */	short		rn;		/* input record number */	struct stat	stb;		/* struct for stat ops */	prog = *argv;	version = "010";	while( (opt = getopt( argc, argv, "df:v:" )) != EOF )	{		switch( opt )		{		case 'd':			flags |= DEBUGON;			break;		case 'f':			if( chdir( optarg ) )			{				(void) fprintf(stderr,					"%s: cannot chdir to %s (%s)\n", prog,					optarg, sys_errlist[errno] );				exit(1);			}			break;		case 'v':			version = optarg;			flags |= VERSION;			break;		default:			Usage();			exit(1);		}	}	if( optind != argc )	/* pick up unflagged mountpath */	{		if( chdir( argv[optind] ) )		{			(void) fprintf(stderr, "%s: cannot chdir to %s (%s)\n",				prog, optarg, sys_errlist[errno] );			exit(1);		}	}	/* set up input and output files */	mi = MiInit( stdin );	i = InvInit( stdout );	/* for all the lines in the input file */	for( *lastpath = '\0', rn = 1; (mip = MiRead( mi )) != NULL; ++rn)	{		path = mip->mi_path;		if( strcmp( path, lastpath ) < 0 )		{			(void) fprintf( stderr, "%s: sort error, record #%d\n",				prog, rn );			exit(1);		}		(void) PathSet( lastpath, path );		if( lstat( path, &stb ) ) 		{				(void) fprintf(stderr,"%s: cannot stat %s (%s)\n",				prog, path, sys_errlist[errno]);			exit(1);		}		if( (stb.st_mode & S_IFMT) == S_IFSOCK )		{			/* error, no sockets permitted */			(void) fprintf(stderr,				"%s: %s: illegal file type code %o\n", prog,				path, stb.st_mode & S_IFMT);			exit(1);		}		ip = StatToInv( &stb );		ip->i_flags =  mip->mi_flags;		(void) InvRecSetRev( ip, version );		(void) InvRecSetPath( ip, path );		(void) InvRecSetSubset( ip, mip->mi_subset );		(void) InvRecSetRef( ip, "none" );		LinkResolve( ip );		switch( ip->i_type )		{		case 'b':	/* block device */		case 'c':	/* char device */		case 'd':	/* directory */			break;		case 'f':	/* straight file */			ip->i_sum = CheckSum( path );		case 'l':	/* link */		case 'p':	/* fifo */			break;		case 's':	/* symbolic link */			SymLink( ip );			break;		default:			(void) fprintf(stderr,				"%s: unknown type '%c', file %s\n", prog,				ip->i_type, path );		}		/* Write finished record to stdout */		(void) InvWrite( i, ip );		}	LinkClear();}/*	static LinkClear() - *		Assert than no unresolved hard links exist. * *	given:	uses global (ResQT *links) *	does:	searches list for unresolved links *	return:	only is there are no unresolved links.*/static LinkClear(){	ResQT	*t;	int	n = 0;	for( t = links; t != NULL; t = t->rq_next )	{		if( t->rq_nlink != 0 )		{			(void) fprintf( stderr, "%s: unresolved nlink %d: %s\n",				prog, t->rq_nlink, t->rq_path );			++n;		}	}	if( n )	{		(void) fprintf( stderr, "%s: %d unresolved hard links\n",			prog, n );		exit(1);	}}/*	static LinkResolve() - *		Resolve Hard Links * *	given:	InvRecT *p - pointer to an InvRecT to resolve *	does:	verifies that the file is not a directory. *		if the link count on the file is > 1, checks to *		see if the file satisfies any pending links. if *		so it is marked type 'l' and the pending link is *		decremented or cleared as appropriate. If the file *		does not satisfy any pending links, it is new! and *		gets queue for resolution. *	return:	nothing *	side:	may modify i_type field of the incomming record. *		may modify the referent field of the incomming record.*/static LinkResolve(p)InvRecT *p;{	ResQT	*t;	if( p->i_type == 'd' || p->i_nlink == 1 )		return;	if( (t = LinkSearch( p, links )) == NULL )	{		t = ResQCreate( p );		t->rq_next = links;		links = t;		return;	}	--(t->rq_nlink);	(void) InvRecSetRef( p, t->rq_path );	p->i_type = 'l';}/*	static ResQT *LinkSearch() - *		Attempt to locate a file in the resolution queue * *	given:	InvRecT *p - a pointer to a file being resolved *		ResQT *l - a pointer to the resolution queue *	does:	searches the resolution queue for a dev/ino match *		on the incomming InvRecT *	return: a pointer to the resolution node if found, else NULL **/static ResQT *LinkSearch(p, l)InvRecT *p;ResQT *l;{	register ResQT	*t;	for( t = l; t != NULL; t = t->rq_next )	{		if( p->i_dev == t->rq_dev && p->i_ino == t->rq_ino )			break;	}	return(t);}/*	ResQT *ResQCreate() - *		Queue up a hard link resolution block * *	given:	InvRecT *p - an InvRecT with the data to be queued *	does:	allocates space for a ResQT and fills in the blanks *	return:	a pointer to the new ResQT*/static ResQT *ResQCreate( p )InvRecT *p;{	register ResQT	*t;	if( (t = ResQNew()) == NULL )		return(NULL);	/* copy in: pathname, dev, ino, linkcount-1.	*/	(void) strcpy( t->rq_path, p->i_path );	t->rq_dev = p->i_dev;	t->rq_ino = p->i_ino;	t->rq_nlink = p->i_nlink - 1;	return(t);}	/*	SymLink() - *		Look up symbolic link information for referrent *		field of an InvRecT. * *	given:	InvRecT *p - an inventory record to work with. *	does:	fill referent field from readlink() info. *	return:	Nothing.*/static SymLink(p)InvRecT *p;{	int	n;	PathT	buf;	if( (n = readlink( p->i_path, buf, sizeof(buf) )) == -1 )	{		(void) fprintf(stderr, "%s: cannot readlink %s (%s)\n", prog,			p->i_path, sys_errlist[errno]);		exit(-1);	}	/* readlink doesnt null terminate result buffer */	buf[n] = '\0';	(void) InvRecSetRef( p, buf );	p->i_sum = 0;}static ResQT *ResQNew(){	return( (ResQT *) malloc( sizeof(ResQT) ) );}

⌨️ 快捷键说明

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