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)
42 Binit(&bin, 0, OREAD);
44 ok = bunzip(1, "<stdout>", &bin);
47 for(i = 0; i < argc; i++)
48 ok &= bunzipf(argv[i], stdout);
51 exits(ok ? nil: "errors");
55 bunzipf(char *file, int stdout)
61 ifd = open(file, OREAD);
63 fprint(2, "bunzip2: can't open %s: %r\n", file);
67 Binit(&bin, ifd, OREAD);
68 if(Bgetc(&bin) != 'B' || Bgetc(&bin) != 'Z' || Bgetc(&bin) != 'h'){
69 fprint(2, "bunzip2: %s is not a bzip2 file\n", file);
80 strcpy(ofile, "<stdout>");
82 s = strrchr(file, '/');
87 strecpy(ofile, ofile+sizeof ofile, s);
88 s = strrchr(ofile, '.');
89 if(s != nil && s != ofile && strcmp(s, ".bz2") == 0)
91 else if(s != nil && (strcmp(s, ".tbz") == 0 || strcmp(s, ".tbz2") == 0))
93 else if(strcmp(file, ofile) == 0){
94 fprint(2, "bunzip2: can't overwrite %s\n", file);
100 ofd = create(ofile, OWRITE, 0666);
102 fprint(2, "bunzip2: can't create %s: %r\n", ofile);
110 ok = bunzip(ofd, ofile, &bin);
114 fprint(2, "bunzip2: can't write %s: %r\n", ofile);
119 if(!stdout && ofd >= 0)
125 bunzip(int ofd, char *ofile, Biobuf *bin)
127 int e, n, done, onemore;
135 memset(&strm, 0, sizeof strm);
136 BZ2_bzDecompressInit(&strm, verbose, 0);
140 strm.next_out = obuf;
141 strm.avail_out = sizeof obuf;
144 Binit(&bout, ofd, OWRITE);
147 * onemore is a crummy hack to go 'round the loop
148 * once after we finish, to flush the output buffer.
153 if(!done && strm.avail_in < sizeof buf) {
155 memmove(buf, strm.next_in, strm.avail_in);
157 n = Bread(bin, buf+strm.avail_in, sizeof(buf)-strm.avail_in);
164 if(strm.avail_out < sizeof obuf) {
165 Bwrite(&bout, obuf, sizeof(obuf)-strm.avail_out);
166 strm.next_out = obuf;
167 strm.avail_out = sizeof obuf;
171 if(strm.avail_in == 0 && strm.avail_out == sizeof obuf)
173 } while((e=BZ2_bzDecompress(&strm)) == BZ_OK || onemore--);
175 if(e != BZ_STREAM_END) {
176 fprint(2, "bunzip2: decompress failed\n");
180 if(BZ2_bzDecompressEnd(&strm) != BZ_OK) {
181 fprint(2, "bunzip2: decompress end failed (can't happen)\n");