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 int bzipf(char*, int);
7 ff3adf60 2004-04-14 devnull static int bzip(char*, long, int, Biobuf*);
8 ff3adf60 2004-04-14 devnull
9 ff3adf60 2004-04-14 devnull static Biobuf bout;
10 ff3adf60 2004-04-14 devnull static int level;
11 ff3adf60 2004-04-14 devnull static int debug;
12 ff3adf60 2004-04-14 devnull static int verbose;
13 ff3adf60 2004-04-14 devnull
14 ff3adf60 2004-04-14 devnull
15 ff3adf60 2004-04-14 devnull static void
16 ff3adf60 2004-04-14 devnull usage(void)
17 ff3adf60 2004-04-14 devnull {
18 ff3adf60 2004-04-14 devnull fprint(2, "usage: bzip2 [-vcD] [-1-9] [file ...]\n");
19 ff3adf60 2004-04-14 devnull exits("usage");
20 ff3adf60 2004-04-14 devnull }
21 ff3adf60 2004-04-14 devnull
22 ff3adf60 2004-04-14 devnull void
23 ff3adf60 2004-04-14 devnull main(int argc, char **argv)
24 ff3adf60 2004-04-14 devnull {
25 ff3adf60 2004-04-14 devnull int i, ok, stdout;
26 892de798 2004-04-19 devnull char **oargv;
27 ff3adf60 2004-04-14 devnull
28 892de798 2004-04-19 devnull oargv = argv;
29 ff3adf60 2004-04-14 devnull level = 6;
30 ff3adf60 2004-04-14 devnull stdout = 0;
31 ff3adf60 2004-04-14 devnull ARGBEGIN{
32 ff3adf60 2004-04-14 devnull case 'D':
33 ff3adf60 2004-04-14 devnull debug++;
34 ff3adf60 2004-04-14 devnull break;
35 ff3adf60 2004-04-14 devnull case 'v':
36 ff3adf60 2004-04-14 devnull verbose++;
37 ff3adf60 2004-04-14 devnull break;
38 ff3adf60 2004-04-14 devnull case 'c':
39 ff3adf60 2004-04-14 devnull stdout++;
40 ff3adf60 2004-04-14 devnull break;
41 b1455f33 2004-04-30 devnull case 'f':
42 b1455f33 2004-04-30 devnull /* force */
43 b1455f33 2004-04-30 devnull break;
44 892de798 2004-04-19 devnull case 'd':
45 892de798 2004-04-19 devnull /*
46 892de798 2004-04-19 devnull * gnu tar expects bzip2 -d to decompress
47 892de798 2004-04-19 devnull * humor it. ugh.
48 892de798 2004-04-19 devnull */
49 892de798 2004-04-19 devnull /* remove -d from command line - magic! */
50 892de798 2004-04-19 devnull if(strcmp(argv[0], "-d") == 0){
51 892de798 2004-04-19 devnull while(*argv++)
52 892de798 2004-04-19 devnull *(argv-1) = *argv;
53 892de798 2004-04-19 devnull }else
54 892de798 2004-04-19 devnull memmove(_args-1, _args, strlen(_args)+1);
55 892de798 2004-04-19 devnull exec("bunzip2", oargv);
56 892de798 2004-04-19 devnull sysfatal("exec bunzip2 failed");
57 892de798 2004-04-19 devnull break;
58 ff3adf60 2004-04-14 devnull case '1': case '2': case '3': case '4':
59 ff3adf60 2004-04-14 devnull case '5': case '6': case '7': case '8': case '9':
60 ff3adf60 2004-04-14 devnull level = ARGC() - '0';
61 ff3adf60 2004-04-14 devnull break;
62 ff3adf60 2004-04-14 devnull default:
63 ff3adf60 2004-04-14 devnull usage();
64 ff3adf60 2004-04-14 devnull break;
65 ff3adf60 2004-04-14 devnull }ARGEND
66 ff3adf60 2004-04-14 devnull
67 ff3adf60 2004-04-14 devnull if(argc == 0){
68 ff3adf60 2004-04-14 devnull Binit(&bout, 1, OWRITE);
69 ff3adf60 2004-04-14 devnull ok = bzip(nil, time(0), 0, &bout);
70 ff3adf60 2004-04-14 devnull Bterm(&bout);
71 ff3adf60 2004-04-14 devnull }else{
72 ff3adf60 2004-04-14 devnull ok = 1;
73 ff3adf60 2004-04-14 devnull for(i = 0; i < argc; i++)
74 ff3adf60 2004-04-14 devnull ok &= bzipf(argv[i], stdout);
75 ff3adf60 2004-04-14 devnull }
76 ff3adf60 2004-04-14 devnull exits(ok ? nil: "errors");
77 ff3adf60 2004-04-14 devnull }
78 ff3adf60 2004-04-14 devnull
79 ff3adf60 2004-04-14 devnull static int
80 ff3adf60 2004-04-14 devnull bzipf(char *file, int stdout)
81 ff3adf60 2004-04-14 devnull {
82 ff3adf60 2004-04-14 devnull Dir *dir;
83 ff3adf60 2004-04-14 devnull char ofile[128], *f, *s;
84 ff3adf60 2004-04-14 devnull int ifd, ofd, ok;
85 ff3adf60 2004-04-14 devnull
86 ff3adf60 2004-04-14 devnull ifd = open(file, OREAD);
87 ff3adf60 2004-04-14 devnull if(ifd < 0){
88 ff3adf60 2004-04-14 devnull fprint(2, "bzip2: can't open %s: %r\n", file);
89 ff3adf60 2004-04-14 devnull return 0;
90 ff3adf60 2004-04-14 devnull }
91 ff3adf60 2004-04-14 devnull dir = dirfstat(ifd);
92 ff3adf60 2004-04-14 devnull if(dir == nil){
93 ff3adf60 2004-04-14 devnull fprint(2, "bzip2: can't stat %s: %r\n", file);
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 if(dir->mode & DMDIR){
98 ff3adf60 2004-04-14 devnull fprint(2, "bzip2: can't compress a directory\n");
99 ff3adf60 2004-04-14 devnull close(ifd);
100 ff3adf60 2004-04-14 devnull free(dir);
101 ff3adf60 2004-04-14 devnull return 0;
102 ff3adf60 2004-04-14 devnull }
103 ff3adf60 2004-04-14 devnull
104 ff3adf60 2004-04-14 devnull if(stdout){
105 ff3adf60 2004-04-14 devnull ofd = 1;
106 ff3adf60 2004-04-14 devnull strcpy(ofile, "<stdout>");
107 ff3adf60 2004-04-14 devnull }else{
108 ff3adf60 2004-04-14 devnull f = strrchr(file, '/');
109 ff3adf60 2004-04-14 devnull if(f != nil)
110 ff3adf60 2004-04-14 devnull f++;
111 ff3adf60 2004-04-14 devnull else
112 ff3adf60 2004-04-14 devnull f = file;
113 ff3adf60 2004-04-14 devnull s = strrchr(f, '.');
114 ff3adf60 2004-04-14 devnull if(s != nil && s != ofile && strcmp(s, ".tar") == 0){
115 ff3adf60 2004-04-14 devnull *s = '\0';
116 ff3adf60 2004-04-14 devnull snprint(ofile, sizeof(ofile), "%s.tbz", f);
117 ff3adf60 2004-04-14 devnull }else
118 ff3adf60 2004-04-14 devnull snprint(ofile, sizeof(ofile), "%s.bz2", f);
119 ff3adf60 2004-04-14 devnull ofd = create(ofile, OWRITE, 0666);
120 ff3adf60 2004-04-14 devnull if(ofd < 0){
121 ff3adf60 2004-04-14 devnull fprint(2, "bzip2: can't open %s: %r\n", ofile);
122 ff3adf60 2004-04-14 devnull free(dir);
123 ff3adf60 2004-04-14 devnull close(ifd);
124 ff3adf60 2004-04-14 devnull return 0;
125 ff3adf60 2004-04-14 devnull }
126 ff3adf60 2004-04-14 devnull }
127 ff3adf60 2004-04-14 devnull
128 ff3adf60 2004-04-14 devnull if(verbose)
129 ff3adf60 2004-04-14 devnull fprint(2, "compressing %s to %s\n", file, ofile);
130 ff3adf60 2004-04-14 devnull
131 ff3adf60 2004-04-14 devnull Binit(&bout, ofd, OWRITE);
132 ff3adf60 2004-04-14 devnull ok = bzip(file, dir->mtime, ifd, &bout);
133 ff3adf60 2004-04-14 devnull if(!ok || Bflush(&bout) < 0){
134 ff3adf60 2004-04-14 devnull fprint(2, "bzip2: error writing %s: %r\n", ofile);
135 ff3adf60 2004-04-14 devnull if(!stdout)
136 ff3adf60 2004-04-14 devnull remove(ofile);
137 ff3adf60 2004-04-14 devnull }
138 ff3adf60 2004-04-14 devnull Bterm(&bout);
139 ff3adf60 2004-04-14 devnull free(dir);
140 ff3adf60 2004-04-14 devnull close(ifd);
141 ff3adf60 2004-04-14 devnull close(ofd);
142 ff3adf60 2004-04-14 devnull return ok;
143 ff3adf60 2004-04-14 devnull }
144 ff3adf60 2004-04-14 devnull
145 ff3adf60 2004-04-14 devnull static int
146 ff3adf60 2004-04-14 devnull bzip(char *file, long mtime, int ifd, Biobuf *bout)
147 ff3adf60 2004-04-14 devnull {
148 ff3adf60 2004-04-14 devnull int e, n, done, onemore;
149 ff3adf60 2004-04-14 devnull char buf[8192];
150 ff3adf60 2004-04-14 devnull char obuf[8192];
151 ff3adf60 2004-04-14 devnull Biobuf bin;
152 ff3adf60 2004-04-14 devnull bz_stream strm;
153 ff3adf60 2004-04-14 devnull
154 ff3adf60 2004-04-14 devnull USED(file);
155 ff3adf60 2004-04-14 devnull USED(mtime);
156 ff3adf60 2004-04-14 devnull
157 ff3adf60 2004-04-14 devnull memset(&strm, 0, sizeof strm);
158 ff3adf60 2004-04-14 devnull BZ2_bzCompressInit(&strm, level, verbose, 0);
159 ff3adf60 2004-04-14 devnull
160 ff3adf60 2004-04-14 devnull strm.next_in = buf;
161 ff3adf60 2004-04-14 devnull strm.avail_in = 0;
162 ff3adf60 2004-04-14 devnull strm.next_out = obuf;
163 ff3adf60 2004-04-14 devnull strm.avail_out = sizeof obuf;
164 ff3adf60 2004-04-14 devnull
165 ff3adf60 2004-04-14 devnull done = 0;
166 ff3adf60 2004-04-14 devnull Binit(&bin, ifd, OREAD);
167 ff3adf60 2004-04-14 devnull
168 ff3adf60 2004-04-14 devnull /*
169 ff3adf60 2004-04-14 devnull * onemore is a crummy hack to go 'round the loop
170 ff3adf60 2004-04-14 devnull * once after we finish, to flush the output buffer.
171 ff3adf60 2004-04-14 devnull */
172 ff3adf60 2004-04-14 devnull onemore = 1;
173 ff3adf60 2004-04-14 devnull SET(e);
174 ff3adf60 2004-04-14 devnull do {
175 ff3adf60 2004-04-14 devnull if(!done && strm.avail_in < sizeof buf) {
176 ff3adf60 2004-04-14 devnull if(strm.avail_in)
177 ff3adf60 2004-04-14 devnull memmove(buf, strm.next_in, strm.avail_in);
178 ff3adf60 2004-04-14 devnull
179 ff3adf60 2004-04-14 devnull n = Bread(&bin, buf+strm.avail_in, sizeof(buf)-strm.avail_in);
180 ff3adf60 2004-04-14 devnull if(n <= 0)
181 ff3adf60 2004-04-14 devnull done = 1;
182 ff3adf60 2004-04-14 devnull else
183 ff3adf60 2004-04-14 devnull strm.avail_in += n;
184 ff3adf60 2004-04-14 devnull strm.next_in = buf;
185 ff3adf60 2004-04-14 devnull }
186 ff3adf60 2004-04-14 devnull if(strm.avail_out < sizeof obuf) {
187 ff3adf60 2004-04-14 devnull Bwrite(bout, obuf, sizeof(obuf)-strm.avail_out);
188 ff3adf60 2004-04-14 devnull strm.next_out = obuf;
189 ff3adf60 2004-04-14 devnull strm.avail_out = sizeof obuf;
190 ff3adf60 2004-04-14 devnull }
191 ff3adf60 2004-04-14 devnull
192 ff3adf60 2004-04-14 devnull if(onemore == 0)
193 ff3adf60 2004-04-14 devnull break;
194 ff3adf60 2004-04-14 devnull } while((e=BZ2_bzCompress(&strm, done ? BZ_FINISH : BZ_RUN)) == BZ_RUN_OK || e == BZ_FINISH_OK || onemore--);
195 ff3adf60 2004-04-14 devnull
196 ff3adf60 2004-04-14 devnull if(e != BZ_STREAM_END) {
197 ff3adf60 2004-04-14 devnull fprint(2, "bzip2: compress failed\n");
198 ff3adf60 2004-04-14 devnull return 0;
199 ff3adf60 2004-04-14 devnull }
200 ff3adf60 2004-04-14 devnull
201 ff3adf60 2004-04-14 devnull if(BZ2_bzCompressEnd(&strm) != BZ_OK) {
202 ff3adf60 2004-04-14 devnull fprint(2, "bzip2: compress end failed (can't happen)\n");
203 ff3adf60 2004-04-14 devnull return 0;
204 ff3adf60 2004-04-14 devnull }
205 ff3adf60 2004-04-14 devnull
206 ff3adf60 2004-04-14 devnull Bterm(&bin);
207 ff3adf60 2004-04-14 devnull
208 ff3adf60 2004-04-14 devnull return 1;
209 ff3adf60 2004-04-14 devnull }