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

📄 unpack.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
/* *	Huffman decompressor *	Usage:	pcat filename... *	or	unpack filename... */#ifndef	lintstatic char sccsid[] = "@(#)unpack.c	4.1	ULTRIX	7/17/90";#endif#include <stdio.h>#include <setjmp.h>#include <sys/types.h>#include <sys/stat.h>#ifdef lint	int	_void_;#	define VOID	_void_ = (int)#else#	define VOID#endifjmp_buf env;struct	stat status;char	*argv0, *argvk;short	errorm;#define NAMELEN 80#define SUF0	'.'#define SUF1	'z'#define US	037#define RS	036#ifdef u370#define	BLKSIZE	4096	/*u370*/#else#define	BLKSIZE	512#endif/* variables associated with i/o */char	filename[NAMELEN+2];short	infile;short	outfile;short	inleft;char	*inp;char	*outp;char	inbuff[BUFSIZ];char	outbuff[BUFSIZ];/* the dictionary */long	origsize;short	maxlev;short	intnodes[25];char	*tree[25];char	characters[256];char	*eof;/* read in the dictionary portion and build decoding structures *//* return 1 if successful, 0 otherwise */getdict (){	register int c, i, nchildren;	/*	 * check two-byte header	 * get size of original file,	 * get number of levels in maxlev,	 * get number of leaves on level i in intnodes[i],	 * set tree[i] to point to leaves for level i	 */	eof = &characters[0];	inbuff[6] = 25;	inleft = read (infile, &inbuff[0], BUFSIZ);	if (inleft < 0) {		eprintf (".z: read error");		return (0);	}	if (inbuff[0] != US)		goto goof;	if (inbuff[1] == US) {		/* oldstyle packing */		if (setjmp (env))			return (0);		return (expand());	}	if (inbuff[1] != RS)		goto goof;	inp = &inbuff[2];	origsize = 0;	for (i=0; i<4; i++)		origsize = origsize*256 + ((*inp++) & 0377);	maxlev = *inp++ & 0377;	if (maxlev > 24) {goof:		eprintf (".z: not in packed format");		return (0);	}	for (i=1; i<=maxlev; i++)		intnodes[i] = *inp++ & 0377;	for (i=1; i<=maxlev; i++) {		tree[i] = eof;		for (c=intnodes[i]; c>0; c--) {			if (eof >= &characters[255])				goto goof;			*eof++ = *inp++;		}	}	*eof++ = *inp++;	intnodes[maxlev] += 2;	inleft -= inp - &inbuff[0];	if (inleft < 0)		goto goof;	/*	 * convert intnodes[i] to be number of	 * internal nodes possessed by level i	 */	nchildren = 0;	for (i=maxlev; i>=1; i--) {		c = intnodes[i];		intnodes[i] = nchildren /= 2;		nchildren += c;	}	return (decode ());}/* unpack the file *//* return 1 if successful, 0 otherwise */decode (){	register int bitsleft, c, i;	int j, lev;	char *p;	outp = &outbuff[0];	lev = 1;	i = 0;	while (1) {		if (inleft <= 0) {			inleft = read (infile, inp = &inbuff[0], BUFSIZ);			if (inleft < 0) {				eprintf (".z: read error");				return (0);			}		}		if (--inleft < 0) {uggh:			eprintf (".z: unpacking error");			return (0);		}		c = *inp++;		bitsleft = 8;		while (--bitsleft >= 0) {			i *= 2;			if (c & 0200)				i++;			c <<= 1;			if ((j = i - intnodes[lev]) >= 0) {				p = &tree[lev][j];				if (p == eof) {					c = outp - &outbuff[0];					if (write (outfile, &outbuff[0], c) != c) {wrerr:						eprintf (": write error");						return (0);					}					origsize -= c;					if (origsize != 0)						goto uggh;					return (1);				}				*outp++ = *p;				if (outp == &outbuff[BUFSIZ]) {					if (write (outfile, outp = &outbuff[0], BUFSIZ) != BUFSIZ)						goto wrerr;					origsize -= BUFSIZ;				}				lev = 1;				i = 0;			} else				lev++;		}	}}main (argc, argv)	char *argv[];{	register i, k;	int sep, pcat = 0;	register char *p1, *cp;	int fcount = 0;		/* failure count */	p1 = *argv;	while(*p1++);		/* Point p1 to end of argv[0] string */	while(--p1 >= *argv)		if(*p1 == '/')break;	*argv = p1 + 1;	argv0 = argv[0];	if(**argv == 'p')pcat++;	/* User entered pcat (or /xx/xx/pcat) */	for (k=1; k<argc; k++) {		errorm = 0;		sep = -1;		cp = filename;		argvk = argv[k];		for (i=0; i < (NAMELEN-3) && (*cp = argvk[i]); i++)			if (*cp++ == '/')				sep = i;		if (cp[-1] == SUF1 && cp[-2] == SUF0) {			argvk[i-2] = '\0'; /* Remove suffix and try again */			k--;			continue;		}		fcount++;	/* expect the worst */		if (i >= (NAMELEN-3) || (i - sep) > 13) {			eprintf (": file name too long");			goto done;		}		*cp++ = SUF0;		*cp++ = SUF1;		*cp = '\0';		if ((infile = open (filename, 0)) == -1) {			eprintf (".z: cannot open");			goto done;		}		if (pcat)			outfile = 1;	/* standard output */		else {			if (stat (argvk, &status) != -1) {				eprintf (": already exists");				goto done;			}			VOID fstat (infile, &status);			if (status.st_nlink != 1)				eprintf (".z: Warning: file has links");			if ((outfile = creat (argvk, (int) status.st_mode&07777)) == -1) {				eprintf (": cannot create");				goto done;			}			if (chmod (argvk, (int) status.st_mode) != 0)			    VOID fprintf(stderr, "can't change mode to %o\n", status.st_mode);			VOID chown (argvk, status.st_uid, status.st_gid);		}		if (getdict ()) {	/* unpack */			fcount--; 	/* success after all */			if (!pcat) {				time_t	ftimes[2];				eprintf (": unpacked");				VOID unlink (filename);				/*				 * preserve acc & mod dates				 */				ftimes[0] = status.st_atime;				ftimes[1] = status.st_mtime;				VOID utime (argvk, ftimes);			}		}		else			if (!pcat)				VOID unlink (argvk);done:		if (errorm)			VOID fprintf (stderr, "\n");		VOID close (infile);		if (!pcat)			VOID close (outfile);	}	return (fcount);}eprintf (s)	char *s;{	if (!errorm) {		errorm = 1;		VOID fprintf (stderr, "%s: %s", argv0, argvk);	}	VOID fprintf (stderr, s);}/* * This code is for unpacking files that * were packed using the previous algorithm. */int	Tree[1024];expand (){	register tp, bit;	short word;	int keysize, i, *t;	outp = outbuff;	inp = &inbuff[2];	inleft -= 2;	origsize = ((long) (unsigned) getword ())*256*256;	origsize += (unsigned) getword ();	t = Tree;	for (keysize = getword (); keysize--; ) {		if ((i = getch ()) == 0377)			*t++ = getword ();		else			*t++ = i & 0377;	}	bit = tp = 0;	for (;;) {		if (bit <= 0) {			word = getword ();			bit = 16;		}		tp += Tree[tp + (word<0)];		word <<= 1;		bit--;		if (Tree[tp] == 0) {			putch (Tree[tp+1]);			tp = 0;			if ((origsize -= 1) == 0) {				if (write (outfile, outbuff, outp - outbuff)					== (outp - outbuff) )					return(1);				eprintf(": write error");				return(0);			}		}	}}getch (){	if (inleft <= 0) {		inleft = read (infile, inp = inbuff, BUFSIZ);		if (inleft < 0) {			eprintf (".z: read error");			longjmp (env, 1);		}	}	inleft--;	return (*inp++ & 0377);}getword (){	register char c;	register d;	c = getch ();	d = getch ();	d <<= 8;	d |= c & 0377;	return (d);}putch (c)	char c;{	register n;	*outp++ = c;	if (outp == &outbuff[BUFSIZ]) {		n = write (outfile, outp = outbuff, BUFSIZ);		if (n < BUFSIZ) {			eprintf (": write error");			longjmp (env, 2);		}	}}

⌨️ 快捷键说明

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