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

📄 gzip.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <flate.h>#include "gzip.h"static	int	gzipf(char*, int);static	int	gzip(char*, long, int, Biobuf*);static	int	crcread(void *fd, void *buf, int n);static	int	gzwrite(void *bout, void *buf, int n);static	Biobuf	bout;static	ulong	crc;static	ulong	*crctab;static	int	debug;static	int	eof;static	int	level;static	ulong	totr;static	int	verbose;voidusage(void){	fprint(2, "usage: gzip [-vcD] [-1-9] [file ...]\n");	exits("usage");}voidmain(int argc, char *argv[]){	int i, ok, stdout;	level = 6;	stdout = 0;	ARGBEGIN{	case 'D':		debug++;		break;	case 'v':		verbose++;		break;	case 'c':		stdout = 1;		break;	case '1': case '2': case '3': case '4':	case '5': case '6': case '7': case '8': case '9':		level = ARGC() - '0';		break;	default:		usage();		break;	}ARGEND	crctab = mkcrctab(GZCRCPOLY);	ok = deflateinit();	if(ok != FlateOk)		sysfatal("deflateinit failed: %s\n", flateerr(ok));	if(argc == 0){		Binit(&bout, 1, OWRITE);		ok = gzip(nil, time(0), 0, &bout);		Bterm(&bout);	}else{		ok = 1;		for(i = 0; i < argc; i++)			ok &= gzipf(argv[i], stdout);	}	exits(ok ? nil: "errors");}static intgzipf(char *file, int stdout){	Dir *dir;	char ofile[256], *f, *s;	int ifd, ofd, ok;	ifd = open(file, OREAD);	if(ifd < 0){		fprint(2, "gzip: can't open %s: %r\n", file);		return 0;	}	dir = dirfstat(ifd);	if(dir == nil){		fprint(2, "gzip: can't stat %s: %r\n", file);		close(ifd);		return 0;	}	if(dir->mode & DMDIR){		fprint(2, "gzip: can't compress a directory\n");		close(ifd);		free(dir);		return 0;	}	if(stdout){		ofd = 1;		strcpy(ofile, "<stdout>");	}else{		f = strrchr(file, '/');		if(f != nil)			f++;		else			f = file;		s = strrchr(f, '.');		if(s != nil && s != ofile && strcmp(s, ".tar") == 0){			*s = '\0';			snprint(ofile, sizeof(ofile), "%s.tgz", f);		}else			snprint(ofile, sizeof(ofile), "%s.gz", f);		ofd = create(ofile, OWRITE, 0666);		if(ofd < 0){			fprint(2, "gzip: can't open %s: %r\n", ofile);			close(ifd);			return 0;		}	}	if(verbose)		fprint(2, "compressing %s to %s\n", file, ofile);	Binit(&bout, ofd, OWRITE);	ok = gzip(file, dir->mtime, ifd, &bout);	if(!ok || Bflush(&bout) < 0){		fprint(2, "gzip: error writing %s: %r\n", ofile);		if(!stdout)			remove(ofile);	}	Bterm(&bout);	free(dir);	close(ifd);	close(ofd);	return ok;}static intgzip(char *file, long mtime, int ifd, Biobuf *bout){	int flags, err;	flags = 0;	Bputc(bout, GZMAGIC1);	Bputc(bout, GZMAGIC2);	Bputc(bout, GZDEFLATE);	if(file != nil)		flags |= GZFNAME;	Bputc(bout, flags);	Bputc(bout, mtime);	Bputc(bout, mtime>>8);	Bputc(bout, mtime>>16);	Bputc(bout, mtime>>24);	Bputc(bout, 0);	Bputc(bout, GZOSINFERNO);	if(flags & GZFNAME)		Bwrite(bout, file, strlen(file)+1);	crc = 0;	eof = 0;	totr = 0;	err = deflate(bout, gzwrite, (void*)ifd, crcread, level, debug);	if(err != FlateOk){		fprint(2, "gzip: deflate failed: %s\n", flateerr(err));		return 0;	}	Bputc(bout, crc);	Bputc(bout, crc>>8);	Bputc(bout, crc>>16);	Bputc(bout, crc>>24);	Bputc(bout, totr);	Bputc(bout, totr>>8);	Bputc(bout, totr>>16);	Bputc(bout, totr>>24);	return 1;}static intcrcread(void *fd, void *buf, int n){	int nr, m;	nr = 0;	for(; !eof && n > 0; n -= m){		m = read((int)(uintptr)fd, (char*)buf+nr, n);		if(m <= 0){			eof = 1;			if(m < 0)				return -1;			break;		}		nr += m;	}	crc = blockcrc(crctab, crc, buf, nr);	totr += nr;	return nr;}static intgzwrite(void *bout, void *buf, int n){	if(n != Bwrite(bout, buf, n)){		eof = 1;		return -1;	}	return n;}

⌨️ 快捷键说明

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