xref: /plan9/sys/src/cmd/gzip/zip.c (revision 14cc0f535177405a84c5b73603a98e5db6674719)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
480ee5cbfSDavid du Colombier #include <flate.h>
57dd7cddfSDavid du Colombier #include "zip.h"
67dd7cddfSDavid du Colombier 
77dd7cddfSDavid du Colombier enum
87dd7cddfSDavid du Colombier {
97dd7cddfSDavid du Colombier 	HeadAlloc	= 64,
107dd7cddfSDavid du Colombier };
117dd7cddfSDavid du Colombier 
127dd7cddfSDavid du Colombier static	void	zip(Biobuf *bout, char *file, int stdout);
137dd7cddfSDavid du Colombier static	void	zipDir(Biobuf *bout, int fd, ZipHead *zh, int stdout);
147dd7cddfSDavid du Colombier static	int	crcread(void *fd, void *buf, int n);
157dd7cddfSDavid du Colombier static	int	zwrite(void *bout, void *buf, int n);
167dd7cddfSDavid du Colombier static	void	put4(Biobuf *b, ulong v);
177dd7cddfSDavid du Colombier static	void	put2(Biobuf *b, int v);
187dd7cddfSDavid du Colombier static	void	put1(Biobuf *b, int v);
197dd7cddfSDavid du Colombier static	void	header(Biobuf *bout, ZipHead *zh);
207dd7cddfSDavid du Colombier static	void	trailer(Biobuf *bout, ZipHead *zh, vlong off);
217dd7cddfSDavid du Colombier static	void	putCDir(Biobuf *bout);
227dd7cddfSDavid du Colombier 
237dd7cddfSDavid du Colombier static	void	error(char*, ...);
247dd7cddfSDavid du Colombier #pragma	varargck	argpos	error	1
257dd7cddfSDavid du Colombier 
267dd7cddfSDavid du Colombier static	Biobuf	bout;
277dd7cddfSDavid du Colombier static	ulong	crc;
2880ee5cbfSDavid du Colombier static	ulong	*crctab;
297dd7cddfSDavid du Colombier static	int	debug;
307dd7cddfSDavid du Colombier static	int	eof;
317dd7cddfSDavid du Colombier static	int	level;
327dd7cddfSDavid du Colombier static	int	nzheads;
337dd7cddfSDavid du Colombier static	ulong	totr;
347dd7cddfSDavid du Colombier static	ulong	totw;
357dd7cddfSDavid du Colombier static	int	verbose;
367dd7cddfSDavid du Colombier static	int	zhalloc;
377dd7cddfSDavid du Colombier static	ZipHead	*zheads;
387dd7cddfSDavid du Colombier static	jmp_buf	zjmp;
397dd7cddfSDavid du Colombier 
407dd7cddfSDavid du Colombier void
usage(void)417dd7cddfSDavid du Colombier usage(void)
427dd7cddfSDavid du Colombier {
437dd7cddfSDavid du Colombier 	fprint(2, "usage: zip [-vD] [-1-9] [-f zipfile] file ...\n");
447dd7cddfSDavid du Colombier 	exits("usage");
457dd7cddfSDavid du Colombier }
467dd7cddfSDavid du Colombier 
477dd7cddfSDavid du Colombier void
main(int argc,char * argv[])487dd7cddfSDavid du Colombier main(int argc, char *argv[])
497dd7cddfSDavid du Colombier {
507dd7cddfSDavid du Colombier 	char *zfile;
5180ee5cbfSDavid du Colombier 	int i, fd, err;
527dd7cddfSDavid du Colombier 
537dd7cddfSDavid du Colombier 	zfile = nil;
547dd7cddfSDavid du Colombier 	level = 6;
557dd7cddfSDavid du Colombier 	ARGBEGIN{
567dd7cddfSDavid du Colombier 	case 'D':
577dd7cddfSDavid du Colombier 		debug++;
587dd7cddfSDavid du Colombier 		break;
597dd7cddfSDavid du Colombier 	case 'f':
607dd7cddfSDavid du Colombier 		zfile = ARGF();
617dd7cddfSDavid du Colombier 		if(zfile == nil)
627dd7cddfSDavid du Colombier 			usage();
637dd7cddfSDavid du Colombier 		break;
647dd7cddfSDavid du Colombier 	case 'v':
657dd7cddfSDavid du Colombier 		verbose++;
667dd7cddfSDavid du Colombier 		break;
677dd7cddfSDavid du Colombier 	case '1': case '2': case '3': case '4':
687dd7cddfSDavid du Colombier 	case '5': case '6': case '7': case '8': case '9':
697dd7cddfSDavid du Colombier 		level = ARGC() - '0';
707dd7cddfSDavid du Colombier 		break;
717dd7cddfSDavid du Colombier 	default:
727dd7cddfSDavid du Colombier 		usage();
737dd7cddfSDavid du Colombier 		break;
747dd7cddfSDavid du Colombier 	}ARGEND
757dd7cddfSDavid du Colombier 
767dd7cddfSDavid du Colombier 	if(argc == 0)
777dd7cddfSDavid du Colombier 		usage();
787dd7cddfSDavid du Colombier 
7980ee5cbfSDavid du Colombier 	crctab = mkcrctab(ZCrcPoly);
8080ee5cbfSDavid du Colombier 	err = deflateinit();
8180ee5cbfSDavid du Colombier 	if(err != FlateOk)
82*14cc0f53SDavid du Colombier 		sysfatal("deflateinit failed: %s", flateerr(err));
837dd7cddfSDavid du Colombier 
847dd7cddfSDavid du Colombier 	if(zfile == nil)
857dd7cddfSDavid du Colombier 		fd = 1;
867dd7cddfSDavid du Colombier 	else{
877dd7cddfSDavid du Colombier 		fd = create(zfile, OWRITE, 0664);
887dd7cddfSDavid du Colombier 		if(fd < 0)
89*14cc0f53SDavid du Colombier 			sysfatal("can't create %s: %r", zfile);
907dd7cddfSDavid du Colombier 	}
917dd7cddfSDavid du Colombier 	Binit(&bout, fd, OWRITE);
927dd7cddfSDavid du Colombier 
937dd7cddfSDavid du Colombier 	if(setjmp(zjmp)){
947dd7cddfSDavid du Colombier 		if(zfile != nil){
957dd7cddfSDavid du Colombier 			fprint(2, "zip: removing output file %s\n", zfile);
967dd7cddfSDavid du Colombier 			remove(zfile);
977dd7cddfSDavid du Colombier 		}
987dd7cddfSDavid du Colombier 		exits("errors");
997dd7cddfSDavid du Colombier 	}
1007dd7cddfSDavid du Colombier 
1017dd7cddfSDavid du Colombier 	for(i = 0; i < argc; i++)
1027dd7cddfSDavid du Colombier 		zip(&bout, argv[i], zfile == nil);
1037dd7cddfSDavid du Colombier 
1047dd7cddfSDavid du Colombier 	putCDir(&bout);
1057dd7cddfSDavid du Colombier 
1067dd7cddfSDavid du Colombier 	exits(nil);
1077dd7cddfSDavid du Colombier }
1087dd7cddfSDavid du Colombier 
1097dd7cddfSDavid du Colombier static void
zip(Biobuf * bout,char * file,int stdout)1107dd7cddfSDavid du Colombier zip(Biobuf *bout, char *file, int stdout)
1117dd7cddfSDavid du Colombier {
1127dd7cddfSDavid du Colombier 	Tm *t;
1137dd7cddfSDavid du Colombier 	ZipHead *zh;
1149a747e4fSDavid du Colombier 	Dir *dir;
1157dd7cddfSDavid du Colombier 	vlong off;
11680ee5cbfSDavid du Colombier 	int fd, err;
1177dd7cddfSDavid du Colombier 
1187dd7cddfSDavid du Colombier 	fd = open(file, OREAD);
1197dd7cddfSDavid du Colombier 	if(fd < 0)
1207dd7cddfSDavid du Colombier 		error("can't open %s: %r", file);
1219a747e4fSDavid du Colombier 	dir = dirfstat(fd);
1229a747e4fSDavid du Colombier 	if(dir == nil)
1237dd7cddfSDavid du Colombier 		error("can't stat %s: %r", file);
1247dd7cddfSDavid du Colombier 
1257dd7cddfSDavid du Colombier 	/*
1267dd7cddfSDavid du Colombier 	 * create the header
1277dd7cddfSDavid du Colombier 	 */
1287dd7cddfSDavid du Colombier 	if(nzheads >= zhalloc){
1297dd7cddfSDavid du Colombier 		zhalloc += HeadAlloc;
1307dd7cddfSDavid du Colombier 		zheads = realloc(zheads, zhalloc * sizeof(ZipHead));
1317dd7cddfSDavid du Colombier 		if(zheads == nil)
1327dd7cddfSDavid du Colombier 			error("out of memory");
1337dd7cddfSDavid du Colombier 	}
1347dd7cddfSDavid du Colombier 	zh = &zheads[nzheads++];
1357dd7cddfSDavid du Colombier 	zh->madeos = ZDos;
1367dd7cddfSDavid du Colombier 	zh->madevers = (2 * 10) + 0;
1377dd7cddfSDavid du Colombier 	zh->extos = ZDos;
1387dd7cddfSDavid du Colombier 	zh->extvers = (2 * 10) + 0;
1397dd7cddfSDavid du Colombier 
1409a747e4fSDavid du Colombier 	t = localtime(dir->mtime);
1417dd7cddfSDavid du Colombier 	zh->modtime = (t->hour<<11) | (t->min<<5) | (t->sec>>1);
1427dd7cddfSDavid du Colombier 	zh->moddate = ((t->year-80)<<9) | ((t->mon+1)<<5) | t->mday;
1437dd7cddfSDavid du Colombier 
1447dd7cddfSDavid du Colombier 	zh->flags = 0;
1457dd7cddfSDavid du Colombier 	zh->crc = 0;
1467dd7cddfSDavid du Colombier 	zh->csize = 0;
1477dd7cddfSDavid du Colombier 	zh->uncsize = 0;
1487dd7cddfSDavid du Colombier 	zh->file = strdup(file);
1497dd7cddfSDavid du Colombier 	if(zh->file == nil)
1507dd7cddfSDavid du Colombier 		error("out of memory");
1517dd7cddfSDavid du Colombier 	zh->iattr = 0;
1527dd7cddfSDavid du Colombier 	zh->eattr = ZDArch;
1539a747e4fSDavid du Colombier 	if((dir->mode & 0700) == 0)
1547dd7cddfSDavid du Colombier 		zh->eattr |= ZDROnly;
1557dd7cddfSDavid du Colombier 	zh->off = Boffset(bout);
1567dd7cddfSDavid du Colombier 
1579a747e4fSDavid du Colombier 	if(dir->mode & DMDIR){
1587dd7cddfSDavid du Colombier 		zh->eattr |= ZDDir;
1597dd7cddfSDavid du Colombier 		zh->meth = 0;
1607dd7cddfSDavid du Colombier 		zipDir(bout, fd, zh, stdout);
1617dd7cddfSDavid du Colombier 	}else{
1627dd7cddfSDavid du Colombier 		zh->meth = 8;
1637dd7cddfSDavid du Colombier 		if(stdout)
1647dd7cddfSDavid du Colombier 			zh->flags |= ZTrailInfo;
1657dd7cddfSDavid du Colombier 		off = Boffset(bout);
1667dd7cddfSDavid du Colombier 		header(bout, zh);
1677dd7cddfSDavid du Colombier 
1687dd7cddfSDavid du Colombier 		crc = 0;
1697dd7cddfSDavid du Colombier 		eof = 0;
1707dd7cddfSDavid du Colombier 		totr = 0;
1717dd7cddfSDavid du Colombier 		totw = 0;
17280ee5cbfSDavid du Colombier 		err = deflate(bout, zwrite, (void*)fd, crcread, level, debug);
17380ee5cbfSDavid du Colombier 		if(err != FlateOk)
17480ee5cbfSDavid du Colombier 			error("deflate failed: %s: %r", flateerr(err));
1757dd7cddfSDavid du Colombier 
1767dd7cddfSDavid du Colombier 		zh->csize = totw;
1777dd7cddfSDavid du Colombier 		zh->uncsize = totr;
1787dd7cddfSDavid du Colombier 		zh->crc = crc;
1797dd7cddfSDavid du Colombier 		trailer(bout, zh, off);
1807dd7cddfSDavid du Colombier 	}
1817dd7cddfSDavid du Colombier 	close(fd);
1829a747e4fSDavid du Colombier 	free(dir);
1837dd7cddfSDavid du Colombier }
1847dd7cddfSDavid du Colombier 
1857dd7cddfSDavid du Colombier static void
zipDir(Biobuf * bout,int fd,ZipHead * zh,int stdout)1867dd7cddfSDavid du Colombier zipDir(Biobuf *bout, int fd, ZipHead *zh, int stdout)
1877dd7cddfSDavid du Colombier {
1889a747e4fSDavid du Colombier 	Dir *dirs;
1897dd7cddfSDavid du Colombier 	char *file, *pfile;
1907dd7cddfSDavid du Colombier 	int i, nf, nd;
1917dd7cddfSDavid du Colombier 
1927dd7cddfSDavid du Colombier 	nf = strlen(zh->file) + 1;
1937dd7cddfSDavid du Colombier 	if(strcmp(zh->file, ".") == 0){
1947dd7cddfSDavid du Colombier 		nzheads--;
1957dd7cddfSDavid du Colombier 		free(zh->file);
1967dd7cddfSDavid du Colombier 		pfile = "";
1977dd7cddfSDavid du Colombier 		nf = 1;
1987dd7cddfSDavid du Colombier 	}else{
1997dd7cddfSDavid du Colombier 		nf++;
2007dd7cddfSDavid du Colombier 		pfile = malloc(nf);
2017dd7cddfSDavid du Colombier 		if(pfile == nil)
2027dd7cddfSDavid du Colombier 			error("out of memory");
2037dd7cddfSDavid du Colombier 		snprint(pfile, nf, "%s/", zh->file);
2047dd7cddfSDavid du Colombier 		free(zh->file);
2057dd7cddfSDavid du Colombier 		zh->file = pfile;
2067dd7cddfSDavid du Colombier 		header(bout, zh);
2077dd7cddfSDavid du Colombier 	}
2087dd7cddfSDavid du Colombier 
2099a747e4fSDavid du Colombier 	nf += 256;	/* plenty of room */
2107dd7cddfSDavid du Colombier 	file = malloc(nf);
2117dd7cddfSDavid du Colombier 	if(file == nil)
2127dd7cddfSDavid du Colombier 		error("out of memory");
213d9306527SDavid du Colombier 	while((nd = dirread(fd, &dirs)) > 0){
2147dd7cddfSDavid du Colombier 		for(i = 0; i < nd; i++){
2157dd7cddfSDavid du Colombier 			snprint(file, nf, "%s%s", pfile, dirs[i].name);
2167dd7cddfSDavid du Colombier 			zip(bout, file, stdout);
2177dd7cddfSDavid du Colombier 		}
2189a747e4fSDavid du Colombier 		free(dirs);
2197dd7cddfSDavid du Colombier 	}
2207dd7cddfSDavid du Colombier }
2217dd7cddfSDavid du Colombier 
2227dd7cddfSDavid du Colombier static void
header(Biobuf * bout,ZipHead * zh)2237dd7cddfSDavid du Colombier header(Biobuf *bout, ZipHead *zh)
2247dd7cddfSDavid du Colombier {
2257dd7cddfSDavid du Colombier 	int flen;
2267dd7cddfSDavid du Colombier 
2277dd7cddfSDavid du Colombier 	if(verbose)
2287dd7cddfSDavid du Colombier 		fprint(2, "adding %s\n", zh->file);
2297dd7cddfSDavid du Colombier 	put4(bout, ZHeader);
2307dd7cddfSDavid du Colombier 	put1(bout, zh->extvers);
2317dd7cddfSDavid du Colombier 	put1(bout, zh->extos);
2327dd7cddfSDavid du Colombier 	put2(bout, zh->flags);
2337dd7cddfSDavid du Colombier 	put2(bout, zh->meth);
2347dd7cddfSDavid du Colombier 	put2(bout, zh->modtime);
2357dd7cddfSDavid du Colombier 	put2(bout, zh->moddate);
2367dd7cddfSDavid du Colombier 	put4(bout, zh->crc);
2377dd7cddfSDavid du Colombier 	put4(bout, zh->csize);
2387dd7cddfSDavid du Colombier 	put4(bout, zh->uncsize);
2397dd7cddfSDavid du Colombier 	flen = strlen(zh->file);
2407dd7cddfSDavid du Colombier 	put2(bout, flen);
2417dd7cddfSDavid du Colombier 	put2(bout, 0);
2427dd7cddfSDavid du Colombier 	if(Bwrite(bout, zh->file, flen) != flen)
2437dd7cddfSDavid du Colombier 		error("write error");
2447dd7cddfSDavid du Colombier }
2457dd7cddfSDavid du Colombier 
2467dd7cddfSDavid du Colombier static void
trailer(Biobuf * bout,ZipHead * zh,vlong off)2477dd7cddfSDavid du Colombier trailer(Biobuf *bout, ZipHead *zh, vlong off)
2487dd7cddfSDavid du Colombier {
2497dd7cddfSDavid du Colombier 	vlong coff;
2507dd7cddfSDavid du Colombier 
2517dd7cddfSDavid du Colombier 	coff = -1;
2527dd7cddfSDavid du Colombier 	if(!(zh->flags & ZTrailInfo)){
2537dd7cddfSDavid du Colombier 		coff = Boffset(bout);
2547dd7cddfSDavid du Colombier 		if(Bseek(bout, off + ZHeadCrc, 0) < 0)
2557dd7cddfSDavid du Colombier 			error("can't seek in archive");
2567dd7cddfSDavid du Colombier 	}
2577dd7cddfSDavid du Colombier 	put4(bout, zh->crc);
2587dd7cddfSDavid du Colombier 	put4(bout, zh->csize);
2597dd7cddfSDavid du Colombier 	put4(bout, zh->uncsize);
2607dd7cddfSDavid du Colombier 	if(!(zh->flags & ZTrailInfo)){
2617dd7cddfSDavid du Colombier 		if(Bseek(bout, coff, 0) < 0)
2627dd7cddfSDavid du Colombier 			error("can't seek in archive");
2637dd7cddfSDavid du Colombier 	}
2647dd7cddfSDavid du Colombier }
2657dd7cddfSDavid du Colombier 
2667dd7cddfSDavid du Colombier static void
cheader(Biobuf * bout,ZipHead * zh)2677dd7cddfSDavid du Colombier cheader(Biobuf *bout, ZipHead *zh)
2687dd7cddfSDavid du Colombier {
2697dd7cddfSDavid du Colombier 	int flen;
2707dd7cddfSDavid du Colombier 
2717dd7cddfSDavid du Colombier 	put4(bout, ZCHeader);
2727dd7cddfSDavid du Colombier 	put1(bout, zh->madevers);
2737dd7cddfSDavid du Colombier 	put1(bout, zh->madeos);
2747dd7cddfSDavid du Colombier 	put1(bout, zh->extvers);
2757dd7cddfSDavid du Colombier 	put1(bout, zh->extos);
2767dd7cddfSDavid du Colombier 	put2(bout, zh->flags & ~ZTrailInfo);
2777dd7cddfSDavid du Colombier 	put2(bout, zh->meth);
2787dd7cddfSDavid du Colombier 	put2(bout, zh->modtime);
2797dd7cddfSDavid du Colombier 	put2(bout, zh->moddate);
2807dd7cddfSDavid du Colombier 	put4(bout, zh->crc);
2817dd7cddfSDavid du Colombier 	put4(bout, zh->csize);
2827dd7cddfSDavid du Colombier 	put4(bout, zh->uncsize);
2837dd7cddfSDavid du Colombier 	flen = strlen(zh->file);
2847dd7cddfSDavid du Colombier 	put2(bout, flen);
2857dd7cddfSDavid du Colombier 	put2(bout, 0);
2867dd7cddfSDavid du Colombier 	put2(bout, 0);
2877dd7cddfSDavid du Colombier 	put2(bout, 0);
2887dd7cddfSDavid du Colombier 	put2(bout, zh->iattr);
2897dd7cddfSDavid du Colombier 	put4(bout, zh->eattr);
2907dd7cddfSDavid du Colombier 	put4(bout, zh->off);
2917dd7cddfSDavid du Colombier 	if(Bwrite(bout, zh->file, flen) != flen)
2927dd7cddfSDavid du Colombier 		error("write error");
2937dd7cddfSDavid du Colombier }
2947dd7cddfSDavid du Colombier 
2957dd7cddfSDavid du Colombier static void
putCDir(Biobuf * bout)2967dd7cddfSDavid du Colombier putCDir(Biobuf *bout)
2977dd7cddfSDavid du Colombier {
2987dd7cddfSDavid du Colombier 	vlong hoff, ecoff;
2997dd7cddfSDavid du Colombier 	int i;
3007dd7cddfSDavid du Colombier 
3017dd7cddfSDavid du Colombier 	hoff = Boffset(bout);
3027dd7cddfSDavid du Colombier 
3037dd7cddfSDavid du Colombier 	for(i = 0; i < nzheads; i++)
3047dd7cddfSDavid du Colombier 		cheader(bout, &zheads[i]);
3057dd7cddfSDavid du Colombier 
3067dd7cddfSDavid du Colombier 	ecoff = Boffset(bout);
3077dd7cddfSDavid du Colombier 
3087dd7cddfSDavid du Colombier 	if(nzheads >= (1 << 16))
3097dd7cddfSDavid du Colombier 		error("too many entries in zip file: max %d", (1 << 16) - 1);
3107dd7cddfSDavid du Colombier 	put4(bout, ZECHeader);
3117dd7cddfSDavid du Colombier 	put2(bout, 0);
3127dd7cddfSDavid du Colombier 	put2(bout, 0);
3137dd7cddfSDavid du Colombier 	put2(bout, nzheads);
3147dd7cddfSDavid du Colombier 	put2(bout, nzheads);
3157dd7cddfSDavid du Colombier 	put4(bout, ecoff - hoff);
3167dd7cddfSDavid du Colombier 	put4(bout, hoff);
3177dd7cddfSDavid du Colombier 	put2(bout, 0);
3187dd7cddfSDavid du Colombier }
3197dd7cddfSDavid du Colombier 
3207dd7cddfSDavid du Colombier static int
crcread(void * fd,void * buf,int n)3217dd7cddfSDavid du Colombier crcread(void *fd, void *buf, int n)
3227dd7cddfSDavid du Colombier {
3237dd7cddfSDavid du Colombier 	int nr, m;
3247dd7cddfSDavid du Colombier 
3257dd7cddfSDavid du Colombier 	nr = 0;
3267dd7cddfSDavid du Colombier 	for(; !eof && n > 0; n -= m){
32774f16c81SDavid du Colombier 		m = read((int)(uintptr)fd, (char*)buf+nr, n);
3287dd7cddfSDavid du Colombier 		if(m <= 0){
3297dd7cddfSDavid du Colombier 			eof = 1;
33080ee5cbfSDavid du Colombier 			if(m < 0)
33180ee5cbfSDavid du Colombier {
33280ee5cbfSDavid du Colombier fprint(2, "input error %r\n");
33380ee5cbfSDavid du Colombier 				return -1;
33480ee5cbfSDavid du Colombier }
3357dd7cddfSDavid du Colombier 			break;
3367dd7cddfSDavid du Colombier 		}
3377dd7cddfSDavid du Colombier 		nr += m;
3387dd7cddfSDavid du Colombier 	}
33980ee5cbfSDavid du Colombier 	crc = blockcrc(crctab, crc, buf, nr);
3407dd7cddfSDavid du Colombier 	totr += nr;
3417dd7cddfSDavid du Colombier 	return nr;
3427dd7cddfSDavid du Colombier }
3437dd7cddfSDavid du Colombier 
3447dd7cddfSDavid du Colombier static int
zwrite(void * bout,void * buf,int n)3457dd7cddfSDavid du Colombier zwrite(void *bout, void *buf, int n)
3467dd7cddfSDavid du Colombier {
3477dd7cddfSDavid du Colombier 	if(n != Bwrite(bout, buf, n)){
3487dd7cddfSDavid du Colombier 		eof = 1;
3497dd7cddfSDavid du Colombier 		return -1;
3507dd7cddfSDavid du Colombier 	}
3517dd7cddfSDavid du Colombier 	totw += n;
3527dd7cddfSDavid du Colombier 	return n;
3537dd7cddfSDavid du Colombier }
3547dd7cddfSDavid du Colombier 
3557dd7cddfSDavid du Colombier static void
put4(Biobuf * b,ulong v)3567dd7cddfSDavid du Colombier put4(Biobuf *b, ulong v)
3577dd7cddfSDavid du Colombier {
3587dd7cddfSDavid du Colombier 	int i;
3597dd7cddfSDavid du Colombier 
3607dd7cddfSDavid du Colombier 	for(i = 0; i < 4; i++){
3617dd7cddfSDavid du Colombier 		if(Bputc(b, v) < 0)
3627dd7cddfSDavid du Colombier 			error("write error");
3637dd7cddfSDavid du Colombier 		v >>= 8;
3647dd7cddfSDavid du Colombier 	}
3657dd7cddfSDavid du Colombier }
3667dd7cddfSDavid du Colombier 
3677dd7cddfSDavid du Colombier static void
put2(Biobuf * b,int v)3687dd7cddfSDavid du Colombier put2(Biobuf *b, int v)
3697dd7cddfSDavid du Colombier {
3707dd7cddfSDavid du Colombier 	int i;
3717dd7cddfSDavid du Colombier 
3727dd7cddfSDavid du Colombier 	for(i = 0; i < 2; i++){
3737dd7cddfSDavid du Colombier 		if(Bputc(b, v) < 0)
3747dd7cddfSDavid du Colombier 			error("write error");
3757dd7cddfSDavid du Colombier 		v >>= 8;
3767dd7cddfSDavid du Colombier 	}
3777dd7cddfSDavid du Colombier }
3787dd7cddfSDavid du Colombier 
3797dd7cddfSDavid du Colombier static void
put1(Biobuf * b,int v)3807dd7cddfSDavid du Colombier put1(Biobuf *b, int v)
3817dd7cddfSDavid du Colombier {
3827dd7cddfSDavid du Colombier 	if(Bputc(b, v)< 0)
3837dd7cddfSDavid du Colombier 		error("unexpected eof reading file information");
3847dd7cddfSDavid du Colombier }
3857dd7cddfSDavid du Colombier 
3867dd7cddfSDavid du Colombier static void
error(char * fmt,...)3877dd7cddfSDavid du Colombier error(char *fmt, ...)
3887dd7cddfSDavid du Colombier {
3897dd7cddfSDavid du Colombier 	va_list arg;
3907dd7cddfSDavid du Colombier 
3919a747e4fSDavid du Colombier 	fprint(2, "zip: ");
3927dd7cddfSDavid du Colombier 	va_start(arg, fmt);
3939a747e4fSDavid du Colombier 	vfprint(2, fmt, arg);
3947dd7cddfSDavid du Colombier 	va_end(arg);
3959a747e4fSDavid du Colombier 	fprint(2, "\n");
3967dd7cddfSDavid du Colombier 
3977dd7cddfSDavid du Colombier 	longjmp(zjmp, 1);
3987dd7cddfSDavid du Colombier }
399