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

📄 cpio.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
# ifndef lintstatic char *sccsid = "@(#)cpio.c	4.4	(ULTRIX)	4/11/91";# endif /* not 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.	* *									* ************************************************************************//* * cpio.c *	Modification History *	------------ ------- * *	09-Apr-91	lambert *			Add "compatability mode" (-C flag) to be able to *			read old, "pre-CLD 126 era" binary archives. * *	07-Feb-91	lambert *			Further fix for CLD #126, mentioned below.  Cpio * 			was changed to simply not archive files with inodes *			greater than those representable in 18 bits.  This *			was deemed unacceptable.  Since the inode numbers in *			the archive are not really used (upon extraction the  *			archived inode #'s cannot be replicated - that's a *			function of the underlying filesystem) the algorith  *			was changed to use an "internal" inode  *			number for files.  A map of inodes with multiple links *			was also created, to facilitate maintaining links on *			extraction from the archive.  Additionally, the inode *			counter is kept on a "per device" basis (based on the *			dev number returned by stat()) so cpio can support up *			to 256K distinct inodes per device. * *			Changed EOT message, per Andy's request. * *	18-Sep-90	carito *			Fixed negative uid and gid values.  Specifically, *			extracted sixteen least-significant-bits.  See *			sprintf().  QAR 03546  Version 4FT1 10-JAN-1990 *			service request A900110-1109 * *	08-Aug-90	kegel *			Upgraded *_ino from ushort to ino_t (ulong)  *			and fixed related sscanf to pick up a long *			instead of a short;  ditto related printf. *			A CLD reported that files were being mistakenly *			linked during extraction because of wrap-around *			in the 16-bit inode numbers used within cpio. *			CLD #126  MUH_01595 * *			Also, added code for "MAGIC" fix in cpio.h to *			meet XPG3.  This fixes the problem for which Digital *			has a temporary waiver.  MAGIC was defined as an *			octal number (070707) in cpio.h;  XPG3 expects *			it to be an octal string ("070707").  Look for *			MAGIC and imagic to find the changes - trivial. * *	07-Feb-90	lambert *			Changed declaration of "m_ino" in postml() routine *			from type short to type ushort due to conflict with *			ushort type of "h_ino" in cpio header. * * 	10-Jan-90	lambert *			Added code for "Pflag" processing to support (non-)use  *			of umask when writing out files.  Also added support  *			for named pipes. * *	29-Sep-89	lambert *			Added reference to X/Open compliant <cpio.h> file. * *	20-Aug-89	lambert *			Fixed null pointer problem in main(). * *	27-Sep-88	lambert *			Added code to ensure symbolic "linked to" file name *			is correct (routine: main(), line 475).  (V24_QAR #533) *	 *	24-Aug-87	fries *			Corrected bug to provide correct name *			length for symbolic link data. *			(SMU-01690) * *	 5-Jan-87	fries *			Completed adding symbolic link support *			to PASS, IN and OUT functions. *			Cleaned up code and commented. * *	12-Nov-86	robin *			Added symbolic link support to IN and *			OUT functions. * *	29-May-86	fries	 *			Added copyright notice.	 * *	29-May-86	fries *			corrected typo utime to utimes * */#include <stdio.h>#include <signal.h>#include <sys/file.h>#include <limits.h>#include <cpio.h>#include <errno.h>#ifdef	RT#include <rt/macro.h>#include <rt/types.h>#include <rt/stat.h>#else#include <sys/types.h>#include <sys/stat.h>#endif#define EQ(x,y)	(strcmp(x,y)==0)/* for VAX, Interdata, ... */#define MKSHORT(v,lv) {U.l=1L;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,v[0]=U.s[0],v[1]=U.s[1];}#define IN	1		/* copy in */#define OUT	2		/* copy out */#define PASS	3		/* directory copy */#define HDRSIZE	(Hdr.h_name - (char *)&Hdr)	/* header size minus filename field */#define O_HDRSIZE (O_Hdr.h_name - (char *)&O_Hdr)	/* Old header size minus filename field */#define LINKS	1000		/* max no. of links allowed */#define CHARS	76		/* ASCII header size    */				/* minus filename field */#define BUFSIZE 512		/* In u370, can't use BUFSIZ nor BSIZE */#define CPIOBSZ 4096		/* file read/write */#define printd if(debug) fprintf/* if debug mode(see int below) */#define STAT(n,d) (Slink)?lstat(n,d):stat(n,d) /* type of stat to use */int debug=0;			/* flag to signal debug mode */#ifdef RTextern long filespace;#endif#define	OCTAL	8		/* for MAGIC/imagic fix */#define MAXDEVS 1000		/* max # of h_dev entries per archive */				/* (needed for "inode too big" fix) */struct	stat	Statb, Xstatb;  /* file stat structure  *//* Cpio header format */struct header {	short	h_magic,		h_dev;	ino_t	h_ino;	ushort	h_mode,		h_uid,		h_gid;	short	h_nlink,		h_rdev,		h_mtime[2],		h_namesize,		h_filesize[2];	char	h_name[256];} Hdr;/* Old Cpio header format */struct old_header {	short	h_magic,		h_dev;	ushort	h_ino,		/* Note difference between old + new headers */		h_mode,		h_uid,		h_gid;	short	h_nlink,		h_rdev,		h_mtime[2],		h_namesize,		h_filesize[2];	char	h_name[256];} O_Hdr;unsigned	Bufsize = BUFSIZE;/* default record size */short	Buf[CPIOBSZ/2], *Dbuf;    /* 2048 byte buffer    */char	BBuf[CPIOBSZ], *Cbuf;	  /* Character Mode buffer */char 	*Cptr;			  /* general use char. ptr.*/int	Wct, Wc, Symct;		  /* Counts(words, bytes, and    */				  /* # of bytes in symbolic link */short	*Wp;                      /* Word Pointer(!Cflag) */char	*Cp;			  /* Character Pointer(Cflag) */unsigned	imagic;		  /* integer form of MAGIC from cpio.h */struct linkbuf {	ino_t	real_ino;	dev_t	devnum;	ino_t	fake_ino;	struct	linkbuf *next_lbp;} *lbp;long internal_ino[MAXDEVS]; 	  /* "internal" inode number */short devlist[MAXDEVS];		  /* list of dev #s encountered */short devidx = 0;		  /* global index into devlist array */short last_dev_seen = 0;	  /* more device indexing noise */ino_t next_ino();		  /* make pcc shutup about redeclarations */#ifdef RTshort	Actual_size[2];#endif/* Flags */short	Option,	Dir,	Uncond,	Link,	Rename,	Toc,	Slink,	Verbose,	Select,	Mod_time,	Acc_time,	Cflag,	C_mode,	fflag, 	Pflag,#ifdef RT	Extent,#endif	Swap,	byteswap,	bothswap,	halfswap;/* file descriptors */int	Ifile,	Ofile,	Input = 0,	Output = 1;long	Blocks,	Longfile,	Longtime;char	Fullname[256],	Name[256];int	Pathend;/* File Pointers for tty read and write */FILE	*Rtty,	*Wtty;char	*Pattern[100];char	Strhdr[500];char	*Chdr = Strhdr;char	symstring[BUFSIZE*2];/* Device # , uid #, gid # & Type of File */short	Dev,	Uid,	Gid,	A_directory,	A_special,	A_symlink,#ifdef RT	One_extent,	Multi_extent,#endif	Filetype = S_IFMT;/* External Globals */extern	errno;/* External Functions */char	*malloc();FILE 	*popen();union { long l; short s[2]; char c[4]; } U;/* for VAX, Interdata, ... */long mklong(v)short v[];{	U.l = 1;	if(U.c[0])		U.s[0] = v[1], U.s[1] = v[0];	else		U.s[0] = v[0], U.s[1] = v[1];	return U.l;}/* Main Code Entry Point */main(argc, argv)	int argc;	char **argv;{	char *namep;	register ct;	long	filesz;	register char *fullp;	register i;	int ans, oumask;	signal(SIGSYS, 1);	imagic = (unsigned) strtoul(MAGIC, NULL, OCTAL );	/* check for options signaller */	if(argc < 2)		usage();	/* get uid */	Uid = getuid();	/* save old user mask and set to zero */ 	oumask = umask(0);	/* get group id */	Gid = getgid();	/* set default for patterns to match */	Pattern[0] = "*";	/* handle options */	while(*++argv[1]) {		switch(*argv[1]) {		case 'a':		/* reset access time */			Acc_time++;			break;		case 'B':		/* change record size to 5120 bytes */			Bufsize = 5120;			break;		case 'i':		/* input data */			Option = IN;			if(argc > 2 ) {	/* save patterns, if any */				for(i = 0; (i+2) < argc; ++i)					Pattern[i] = argv[i+2];			}			break;		case 'f':		/* copy all except patterns */			fflag++;			break;		case 'k':		/* read/create symbolic links */			Slink++;			break;		case 'o':		/* output data */			if(argc != 2)				usage();			Option = OUT;			break; 		case 'P':		/* POSIX mode */			Pflag++;			break;		case 'p':		/* directory copy */			if(argc != 3)				usage();			if(access(argv[2], 2) == -1) {accerr:				fprintf(stderr,"cannot write in <%s>\n", argv[2]);				exit(2);			}			/* destination directory */			strcpy(Fullname, argv[2]);			strcat(Fullname, "/");			/* Check for name being a directory */			stat(Fullname, &Xstatb);			if((Xstatb.st_mode&S_IFMT) != S_IFDIR)				goto accerr;			Option = PASS;			Dev = Xstatb.st_dev;			break;		case 'c':		/* ASCII header */			Cflag++;			break;		case 'C':		/* Compatability mode - use old header */			C_mode++;			break;		case 'd':		/* create directories when needed */			Dir++;			break;		case 'l':		/* link files, when necessary */			Link++;			break;		case 'm':		/* retain mod time */			Mod_time++;			break;		case 'r':		/* rename files interactively */			Rename++;			Rtty = fopen("/dev/tty", "r");			Wtty = fopen("/dev/tty", "w");			if(Rtty==NULL || Wtty==NULL) {				fprintf(stderr,				  "Cannot rename (/dev/tty missing)\n");				exit(2);			}			break;		case 'S':		/* swap halfwords */			halfswap++;			Swap++;			break;		case 's':		/* swap bytes */			byteswap++;			Swap++;			break;		case 'b':		/* swap bytes and halfwords */			bothswap++;			Swap++;			break;		case 't':		/* table of contents */			Toc++;			break;		case 'u':		/* copy unconditionally */			Uncond++;			break;		case 'v':		/* verbose table of contents */			Verbose++;			break;		case 'V':		/* big Verbose mode */			Verbose++;			debug++;	/* set "debug" int (see above) */			break;		case '6':		/* for old, sixth-edition files */			Filetype = 060000;			break;#ifdef RT		case 'e':			Extent++;			break;#endif		default:			usage();		}	}	/* Check that the user specified input, output or pass */	if(!Option) {		fprintf(stderr,"Options must include o|i|p\n");		exit(2);	}	/* Only allow compatability mode when reading in */	if (Option != IN && C_mode) {		fprintf(stderr, "-C only valid on copy in operations - ignored\n");		C_mode = 0;	}#ifdef RT		setio(-1,1);	/* turn on physio */#endif	/* if Pflag specified, and user is not root, reset mask to what	   it was originally (POSIX/XOPEN mode) */	if ((Pflag) && (Uid != 0)) umask(oumask);	/* If directory copy and Rename selected together... */	if(Option == PASS) {		if(Rename) {			fprintf(stderr,"Pass and Rename cannot be used together\n");			exit(2);		}		if(Bufsize == 5120) {			printf("`B' option is irrelevant with the '-p' option\n");			printf("Setting Input/Output blocking to %d bytes to a record\n", BUFSIZE);			Bufsize = BUFSIZE;		}	}else  {		if(Cflag)		    Cp = Cbuf = (char *)malloc(Bufsize);		else		    Wp = Dbuf = (short *)malloc(Bufsize);	}	Wct = Bufsize >> 1; /* set word count */	Wc = Bufsize;       /* and byte count */	/* Perform OUTPUT, INPUT, or PASS operations */	switch(Option) {	case OUT:		/* get filename, copy header and file out */		while(getname()) {			if(A_symlink){				Symct=readlink(Hdr.h_name, Cflag? BBuf:(char *)Buf, Cflag? sizeof(BBuf): sizeof(Buf));				if (Symct < 0) {					perror("cpio");					fprintf(stderr,"Cannot read %s\n", Hdr.h_name);					continue;				}				strncpy(symstring,Cflag ? (char *)BBuf : (char *)Buf,Symct);				Cptr = Cflag ? (char *)BBuf : (char *) Buf;				Cptr[Symct] = '\0' ;				symstring[Symct]='\0';				printd(stderr,"Smyct %d\n BUF: %s\n symstring %s\n namesize %d\n filesize %d\n",				Symct,(Cflag?(char *)BBuf:(char *)Buf),symstring,Hdr.h_namesize,Hdr.h_filesize[1]);								/* Write the header */				if ( Cflag )					writehdr(Chdr,CHARS+Hdr.h_namesize);				else					bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);				Cflag? writehdr(BBuf,(int) mklong(Hdr.h_filesize)): bwrite(Buf,(int) mklong(Hdr.h_filesize));				goto setout;			}			if( mklong(Hdr.h_filesize) == 0L) {			if( Cflag )				writehdr(Chdr,CHARS+Hdr.h_namesize);			else				bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);#ifdef RT			if (One_extent || Multi_extent) {			   actsize(0);			   if( Cflag )				writehdr(Chdr,CHARS+Hdr.h_namesize);			   else				bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);			}#endif				continue;			}			if((Ifile = open(Hdr.h_name,O_RDONLY )) < 0) {				fprintf(stderr,"<%s> ?\n", Hdr.h_name);				continue;			}			if ( Cflag )				writehdr(Chdr,CHARS+Hdr.h_namesize);			else				bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);#ifdef RT			if (One_extent || Multi_extent) {			   actsize(Ifile);			   if(Cflag)				writehdr(Chdr,CHARS+Hdr.h_namesize);			   else				bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);			   Hdr.h_filesize[0] = Actual_size[0];			   Hdr.h_filesize[1] = Actual_size[1];			}#endif			for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){				ct = filesz>CPIOBSZ? CPIOBSZ: filesz;				if(read(Ifile, Cflag? BBuf: (char *)Buf, ct) < 0) {					fprintf(stderr,"Cannot read %s\n", Hdr.h_name);					continue;				}				Cflag? writehdr(BBuf,ct): bwrite(Buf,ct);			}			close(Ifile);setout:			if(Acc_time)				utimes(Hdr.h_name, &Statb.st_atime);			if(Verbose)				fprintf(stderr,"%s\n", Hdr.h_name);		}		/* Output the TRAILER data...                     */		/* copy trailer, after all files have been copied */		strcpy(Hdr.h_name, "TRAILER!!!");		Hdr.h_magic = imagic;		MKSHORT(Hdr.h_filesize, 0L);		Hdr.h_namesize = strlen("TRAILER!!!") + 1;		if ( Cflag )  {			bintochar(0L);			writehdr(Chdr,CHARS+Hdr.h_namesize);		}		else			bwrite(&Hdr, HDRSIZE+Hdr.h_namesize);		Cflag? writehdr(Cbuf, Bufsize): bwrite(Dbuf, Bufsize);		break;	case IN:

⌨️ 快捷键说明

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