11 static int bunzipf(char *file, int stdout);
12 static int bunzip(int ofd, char *ofile, Biobuf *bin);
17 fprint(2, "usage: bunzip2 [-cvD] [file ...]\n");
22 main(int argc, char **argv)
40 Binit(&bin, 0, OREAD);
42 ok = bunzip(1, "<stdout>", &bin);
45 for(i = 0; i < argc; i++)
46 ok &= bunzipf(argv[i], stdout);
49 exits(ok ? nil: "errors");
53 bunzipf(char *file, int stdout)
59 ifd = open(file, OREAD);
61 fprint(2, "gunzip: can't open %s: %r\n", file);
65 Binit(&bin, ifd, OREAD);
66 if(Bgetc(&bin) != 'B' || Bgetc(&bin) != 'Z' || Bgetc(&bin) != 'h'){
67 fprint(2, "bunzip2: %s is not a bzip2 file\n", file);
78 strcpy(ofile, "<stdout>");
80 s = strrchr(file, '/');
85 strecpy(ofile, ofile+sizeof ofile, s);
86 s = strrchr(ofile, '.');
87 if(s != nil && s != ofile && strcmp(s, ".bz2") == 0)
89 else if(s != nil && (strcmp(s, ".tbz") == 0 || strcmp(s, ".tbz2") == 0))
91 else if(strcmp(file, ofile) == 0){
92 fprint(2, "bunzip2: can't overwrite %s\n", file);
98 ofd = create(ofile, OWRITE, 0666);
100 fprint(2, "bunzip2: can't create %s: %r\n", ofile);
108 ok = bunzip(ofd, ofile, &bin);
112 fprint(2, "bunzip2: can't write %s: %r\n", ofile);
117 if(!stdout && ofd >= 0)
123 bunzip(int ofd, char *ofile, Biobuf *bin)
125 int e, n, done, onemore;
133 memset(&strm, 0, sizeof strm);
134 BZ2_bzDecompressInit(&strm, verbose, 0);
138 strm.next_out = obuf;
139 strm.avail_out = sizeof obuf;
142 Binit(&bout, ofd, OWRITE);
145 * onemore is a crummy hack to go 'round the loop
146 * once after we finish, to flush the output buffer.
151 if(!done && strm.avail_in < sizeof buf) {
153 memmove(buf, strm.next_in, strm.avail_in);
155 n = Bread(bin, buf+strm.avail_in, sizeof(buf)-strm.avail_in);
162 if(strm.avail_out < sizeof obuf) {
163 Bwrite(&bout, obuf, sizeof(obuf)-strm.avail_out);
164 strm.next_out = obuf;
165 strm.avail_out = sizeof obuf;
169 if(strm.avail_in == 0 && strm.avail_out == sizeof obuf)
171 } while((e=BZ2_bzDecompress(&strm)) == BZ_OK || onemore--);
173 if(e != BZ_STREAM_END) {
174 fprint(2, "bunzip2: decompress failed\n");
178 if(BZ2_bzDecompressEnd(&strm) != BZ_OK) {
179 fprint(2, "bunzip2: decompress end failed (can't happen)\n");