Blame


1 ff3adf60 2004-04-14 devnull #include <u.h>
2 ff3adf60 2004-04-14 devnull #include <libc.h>
3 ff3adf60 2004-04-14 devnull #include <bio.h>
4 ff3adf60 2004-04-14 devnull #include "bzlib.h"
5 ff3adf60 2004-04-14 devnull
6 ff3adf60 2004-04-14 devnull static Biobuf bin;
7 ff3adf60 2004-04-14 devnull static int debug;
8 ff3adf60 2004-04-14 devnull static int verbose;
9 ff3adf60 2004-04-14 devnull static char *delfile;
10 ff3adf60 2004-04-14 devnull static char *infile;
11 ff3adf60 2004-04-14 devnull static int bunzipf(char *file, int stdout);
12 ff3adf60 2004-04-14 devnull static int bunzip(int ofd, char *ofile, Biobuf *bin);
13 ff3adf60 2004-04-14 devnull
14 ff3adf60 2004-04-14 devnull void
15 ff3adf60 2004-04-14 devnull usage(void)
16 ff3adf60 2004-04-14 devnull {
17 ff3adf60 2004-04-14 devnull fprint(2, "usage: bunzip2 [-cvD] [file ...]\n");
18 ff3adf60 2004-04-14 devnull exits("usage");
19 ff3adf60 2004-04-14 devnull }
20 ff3adf60 2004-04-14 devnull
21 ff3adf60 2004-04-14 devnull void
22 ff3adf60 2004-04-14 devnull main(int argc, char **argv)
23 ff3adf60 2004-04-14 devnull {
24 ff3adf60 2004-04-14 devnull int i, ok, stdout;
25 ff3adf60 2004-04-14 devnull
26 ff3adf60 2004-04-14 devnull stdout = 0;
27 ff3adf60 2004-04-14 devnull ARGBEGIN{
28 ff3adf60 2004-04-14 devnull case 'D':
29 ff3adf60 2004-04-14 devnull debug++;
30 ff3adf60 2004-04-14 devnull break;
31 ff3adf60 2004-04-14 devnull case 'c':
32 ff3adf60 2004-04-14 devnull stdout++;
33 ff3adf60 2004-04-14 devnull break;
34 ff3adf60 2004-04-14 devnull case 'v':
35 ff3adf60 2004-04-14 devnull verbose++;
36 ff3adf60 2004-04-14 devnull break;
37 ff3adf60 2004-04-14 devnull }ARGEND
38 ff3adf60 2004-04-14 devnull
39 ff3adf60 2004-04-14 devnull if(argc == 0){
40 ff3adf60 2004-04-14 devnull Binit(&bin, 0, OREAD);
41 ff3adf60 2004-04-14 devnull infile = "<stdin>";
42 ff3adf60 2004-04-14 devnull ok = bunzip(1, "<stdout>", &bin);
43 ff3adf60 2004-04-14 devnull }else{
44 ff3adf60 2004-04-14 devnull ok = 1;
45 ff3adf60 2004-04-14 devnull for(i = 0; i < argc; i++)
46 ff3adf60 2004-04-14 devnull ok &= bunzipf(argv[i], stdout);
47 ff3adf60 2004-04-14 devnull }
48 ff3adf60 2004-04-14 devnull
49 ff3adf60 2004-04-14 devnull exits(ok ? nil: "errors");
50 ff3adf60 2004-04-14 devnull }
51 ff3adf60 2004-04-14 devnull
52 ff3adf60 2004-04-14 devnull static int
53 ff3adf60 2004-04-14 devnull bunzipf(char *file, int stdout)
54 ff3adf60 2004-04-14 devnull {
55 ff3adf60 2004-04-14 devnull char ofile[64], *s;
56 ff3adf60 2004-04-14 devnull int ofd, ifd, ok;
57 ff3adf60 2004-04-14 devnull
58 ff3adf60 2004-04-14 devnull infile = file;
59 ff3adf60 2004-04-14 devnull ifd = open(file, OREAD);
60 ff3adf60 2004-04-14 devnull if(ifd < 0){
61 ff3adf60 2004-04-14 devnull fprint(2, "gunzip: can't open %s: %r\n", file);
62 ff3adf60 2004-04-14 devnull return 0;
63 ff3adf60 2004-04-14 devnull }
64 ff3adf60 2004-04-14 devnull
65 ff3adf60 2004-04-14 devnull Binit(&bin, ifd, OREAD);
66 ff3adf60 2004-04-14 devnull if(Bgetc(&bin) != 'B' || Bgetc(&bin) != 'Z' || Bgetc(&bin) != 'h'){
67 ff3adf60 2004-04-14 devnull fprint(2, "bunzip2: %s is not a bzip2 file\n", file);
68 ff3adf60 2004-04-14 devnull Bterm(&bin);
69 ff3adf60 2004-04-14 devnull close(ifd);
70 ff3adf60 2004-04-14 devnull return 0;
71 ff3adf60 2004-04-14 devnull }
72 ff3adf60 2004-04-14 devnull Bungetc(&bin);
73 ff3adf60 2004-04-14 devnull Bungetc(&bin);
74 ff3adf60 2004-04-14 devnull Bungetc(&bin);
75 ff3adf60 2004-04-14 devnull
76 ff3adf60 2004-04-14 devnull if(stdout){
77 ff3adf60 2004-04-14 devnull ofd = 1;
78 ff3adf60 2004-04-14 devnull strcpy(ofile, "<stdout>");
79 ff3adf60 2004-04-14 devnull }else{
80 ff3adf60 2004-04-14 devnull s = strrchr(file, '/');
81 ff3adf60 2004-04-14 devnull if(s != nil)
82 ff3adf60 2004-04-14 devnull s++;
83 ff3adf60 2004-04-14 devnull else
84 ff3adf60 2004-04-14 devnull s = file;
85 ff3adf60 2004-04-14 devnull strecpy(ofile, ofile+sizeof ofile, s);
86 ff3adf60 2004-04-14 devnull s = strrchr(ofile, '.');
87 ff3adf60 2004-04-14 devnull if(s != nil && s != ofile && strcmp(s, ".bz2") == 0)
88 ff3adf60 2004-04-14 devnull *s = '\0';
89 ff3adf60 2004-04-14 devnull else if(s != nil && (strcmp(s, ".tbz") == 0 || strcmp(s, ".tbz2") == 0))
90 ff3adf60 2004-04-14 devnull strcpy(s, ".tar");
91 ff3adf60 2004-04-14 devnull else if(strcmp(file, ofile) == 0){
92 ff3adf60 2004-04-14 devnull fprint(2, "bunzip2: can't overwrite %s\n", file);
93 ff3adf60 2004-04-14 devnull Bterm(&bin);
94 ff3adf60 2004-04-14 devnull close(ifd);
95 ff3adf60 2004-04-14 devnull return 0;
96 ff3adf60 2004-04-14 devnull }
97 ff3adf60 2004-04-14 devnull
98 ff3adf60 2004-04-14 devnull ofd = create(ofile, OWRITE, 0666);
99 ff3adf60 2004-04-14 devnull if(ofd < 0){
100 ff3adf60 2004-04-14 devnull fprint(2, "bunzip2: can't create %s: %r\n", ofile);
101 ff3adf60 2004-04-14 devnull Bterm(&bin);
102 ff3adf60 2004-04-14 devnull close(ifd);
103 ff3adf60 2004-04-14 devnull return 0;
104 ff3adf60 2004-04-14 devnull }
105 ff3adf60 2004-04-14 devnull delfile = ofile;
106 ff3adf60 2004-04-14 devnull }
107 ff3adf60 2004-04-14 devnull
108 ff3adf60 2004-04-14 devnull ok = bunzip(ofd, ofile, &bin);
109 ff3adf60 2004-04-14 devnull Bterm(&bin);
110 ff3adf60 2004-04-14 devnull close(ifd);
111 ff3adf60 2004-04-14 devnull if(!ok){
112 ff3adf60 2004-04-14 devnull fprint(2, "bunzip2: can't write %s: %r\n", ofile);
113 ff3adf60 2004-04-14 devnull if(delfile)
114 ff3adf60 2004-04-14 devnull remove(delfile);
115 ff3adf60 2004-04-14 devnull }
116 ff3adf60 2004-04-14 devnull delfile = nil;
117 ff3adf60 2004-04-14 devnull if(!stdout && ofd >= 0)
118 ff3adf60 2004-04-14 devnull close(ofd);
119 ff3adf60 2004-04-14 devnull return ok;
120 ff3adf60 2004-04-14 devnull }
121 ff3adf60 2004-04-14 devnull
122 ff3adf60 2004-04-14 devnull static int
123 ff3adf60 2004-04-14 devnull bunzip(int ofd, char *ofile, Biobuf *bin)
124 ff3adf60 2004-04-14 devnull {
125 ff3adf60 2004-04-14 devnull int e, n, done, onemore;
126 ff3adf60 2004-04-14 devnull char buf[8192];
127 ff3adf60 2004-04-14 devnull char obuf[8192];
128 ff3adf60 2004-04-14 devnull Biobuf bout;
129 ff3adf60 2004-04-14 devnull bz_stream strm;
130 ff3adf60 2004-04-14 devnull
131 ff3adf60 2004-04-14 devnull USED(ofile);
132 ff3adf60 2004-04-14 devnull
133 ff3adf60 2004-04-14 devnull memset(&strm, 0, sizeof strm);
134 ff3adf60 2004-04-14 devnull BZ2_bzDecompressInit(&strm, verbose, 0);
135 ff3adf60 2004-04-14 devnull
136 ff3adf60 2004-04-14 devnull strm.next_in = buf;
137 ff3adf60 2004-04-14 devnull strm.avail_in = 0;
138 ff3adf60 2004-04-14 devnull strm.next_out = obuf;
139 ff3adf60 2004-04-14 devnull strm.avail_out = sizeof obuf;
140 ff3adf60 2004-04-14 devnull
141 ff3adf60 2004-04-14 devnull done = 0;
142 ff3adf60 2004-04-14 devnull Binit(&bout, ofd, OWRITE);
143 ff3adf60 2004-04-14 devnull
144 ff3adf60 2004-04-14 devnull /*
145 ff3adf60 2004-04-14 devnull * onemore is a crummy hack to go 'round the loop
146 ff3adf60 2004-04-14 devnull * once after we finish, to flush the output buffer.
147 ff3adf60 2004-04-14 devnull */
148 ff3adf60 2004-04-14 devnull onemore = 1;
149 ff3adf60 2004-04-14 devnull SET(e);
150 ff3adf60 2004-04-14 devnull do {
151 ff3adf60 2004-04-14 devnull if(!done && strm.avail_in < sizeof buf) {
152 ff3adf60 2004-04-14 devnull if(strm.avail_in)
153 ff3adf60 2004-04-14 devnull memmove(buf, strm.next_in, strm.avail_in);
154 ff3adf60 2004-04-14 devnull
155 ff3adf60 2004-04-14 devnull n = Bread(bin, buf+strm.avail_in, sizeof(buf)-strm.avail_in);
156 ff3adf60 2004-04-14 devnull if(n <= 0)
157 ff3adf60 2004-04-14 devnull done = 1;
158 ff3adf60 2004-04-14 devnull else
159 ff3adf60 2004-04-14 devnull strm.avail_in += n;
160 ff3adf60 2004-04-14 devnull strm.next_in = buf;
161 ff3adf60 2004-04-14 devnull }
162 ff3adf60 2004-04-14 devnull if(strm.avail_out < sizeof obuf) {
163 ff3adf60 2004-04-14 devnull Bwrite(&bout, obuf, sizeof(obuf)-strm.avail_out);
164 ff3adf60 2004-04-14 devnull strm.next_out = obuf;
165 ff3adf60 2004-04-14 devnull strm.avail_out = sizeof obuf;
166 ff3adf60 2004-04-14 devnull }
167 ff3adf60 2004-04-14 devnull if(onemore == 0)
168 ff3adf60 2004-04-14 devnull break;
169 ff3adf60 2004-04-14 devnull if(strm.avail_in == 0 && strm.avail_out == sizeof obuf)
170 ff3adf60 2004-04-14 devnull break;
171 ff3adf60 2004-04-14 devnull } while((e=BZ2_bzDecompress(&strm)) == BZ_OK || onemore--);
172 ff3adf60 2004-04-14 devnull
173 ff3adf60 2004-04-14 devnull if(e != BZ_STREAM_END) {
174 ff3adf60 2004-04-14 devnull fprint(2, "bunzip2: decompress failed\n");
175 ff3adf60 2004-04-14 devnull return 0;
176 ff3adf60 2004-04-14 devnull }
177 ff3adf60 2004-04-14 devnull
178 ff3adf60 2004-04-14 devnull if(BZ2_bzDecompressEnd(&strm) != BZ_OK) {
179 ff3adf60 2004-04-14 devnull fprint(2, "bunzip2: decompress end failed (can't happen)\n");
180 ff3adf60 2004-04-14 devnull return 0;
181 ff3adf60 2004-04-14 devnull }
182 ff3adf60 2004-04-14 devnull
183 ff3adf60 2004-04-14 devnull Bterm(&bout);
184 ff3adf60 2004-04-14 devnull
185 ff3adf60 2004-04-14 devnull return 1;
186 ff3adf60 2004-04-14 devnull }