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 <flate.h>
5 ff3adf60 2004-04-14 devnull #include "gzip.h"
6 ff3adf60 2004-04-14 devnull
7 ff3adf60 2004-04-14 devnull static int gzipf(char*, int);
8 ff3adf60 2004-04-14 devnull static int gzip(char*, long, int, Biobuf*);
9 ff3adf60 2004-04-14 devnull static int crcread(void *fd, void *buf, int n);
10 ff3adf60 2004-04-14 devnull static int gzwrite(void *bout, void *buf, int n);
11 ff3adf60 2004-04-14 devnull
12 ff3adf60 2004-04-14 devnull static Biobuf bout;
13 8425b514 2010-02-23 rsc static u32int crc;
14 8425b514 2010-02-23 rsc static u32int *crctab;
15 ff3adf60 2004-04-14 devnull static int debug;
16 ff3adf60 2004-04-14 devnull static int eof;
17 ff3adf60 2004-04-14 devnull static int level;
18 8425b514 2010-02-23 rsc static u32int totr;
19 ff3adf60 2004-04-14 devnull static int verbose;
20 ff3adf60 2004-04-14 devnull
21 ff3adf60 2004-04-14 devnull void
22 ff3adf60 2004-04-14 devnull usage(void)
23 ff3adf60 2004-04-14 devnull {
24 ff3adf60 2004-04-14 devnull fprint(2, "usage: gzip [-vcD] [-1-9] [file ...]\n");
25 ff3adf60 2004-04-14 devnull exits("usage");
26 ff3adf60 2004-04-14 devnull }
27 ff3adf60 2004-04-14 devnull
28 ff3adf60 2004-04-14 devnull void
29 ff3adf60 2004-04-14 devnull main(int argc, char *argv[])
30 ff3adf60 2004-04-14 devnull {
31 ff3adf60 2004-04-14 devnull int i, ok, stdout;
32 892de798 2004-04-19 devnull char **oargv;
33 ff3adf60 2004-04-14 devnull
34 892de798 2004-04-19 devnull oargv = argv;
35 ff3adf60 2004-04-14 devnull level = 6;
36 ff3adf60 2004-04-14 devnull stdout = 0;
37 ff3adf60 2004-04-14 devnull ARGBEGIN{
38 ff3adf60 2004-04-14 devnull case 'D':
39 ff3adf60 2004-04-14 devnull debug++;
40 ff3adf60 2004-04-14 devnull break;
41 892de798 2004-04-19 devnull case 'd':
42 892de798 2004-04-19 devnull /*
43 892de798 2004-04-19 devnull * gnu tar expects gzip -d to decompress
44 892de798 2004-04-19 devnull * humor it. ugh.
45 892de798 2004-04-19 devnull */
46 892de798 2004-04-19 devnull /* remove -d from command line - magic! */
47 892de798 2004-04-19 devnull if(strcmp(argv[0], "-d") == 0){
48 892de798 2004-04-19 devnull while(*argv++)
49 892de798 2004-04-19 devnull *(argv-1) = *argv;
50 892de798 2004-04-19 devnull }else
51 892de798 2004-04-19 devnull memmove(_args-1, _args, strlen(_args)+1);
52 892de798 2004-04-19 devnull exec("gunzip", oargv);
53 892de798 2004-04-19 devnull sysfatal("exec gunzip failed");
54 892de798 2004-04-19 devnull break;
55 b1455f33 2004-04-30 devnull case 'f':
56 b1455f33 2004-04-30 devnull /* force */
57 b1455f33 2004-04-30 devnull break;
58 ff3adf60 2004-04-14 devnull case 'v':
59 ff3adf60 2004-04-14 devnull verbose++;
60 ff3adf60 2004-04-14 devnull break;
61 ff3adf60 2004-04-14 devnull case 'c':
62 ff3adf60 2004-04-14 devnull stdout = 1;
63 ff3adf60 2004-04-14 devnull break;
64 ff3adf60 2004-04-14 devnull case '1': case '2': case '3': case '4':
65 ff3adf60 2004-04-14 devnull case '5': case '6': case '7': case '8': case '9':
66 ff3adf60 2004-04-14 devnull level = ARGC() - '0';
67 ff3adf60 2004-04-14 devnull break;
68 ff3adf60 2004-04-14 devnull default:
69 ff3adf60 2004-04-14 devnull usage();
70 ff3adf60 2004-04-14 devnull break;
71 ff3adf60 2004-04-14 devnull }ARGEND
72 ff3adf60 2004-04-14 devnull
73 ff3adf60 2004-04-14 devnull crctab = mkcrctab(GZCRCPOLY);
74 ff3adf60 2004-04-14 devnull ok = deflateinit();
75 ff3adf60 2004-04-14 devnull if(ok != FlateOk)
76 ff3adf60 2004-04-14 devnull sysfatal("deflateinit failed: %s\n", flateerr(ok));
77 ff3adf60 2004-04-14 devnull
78 ff3adf60 2004-04-14 devnull if(argc == 0){
79 ff3adf60 2004-04-14 devnull Binit(&bout, 1, OWRITE);
80 ff3adf60 2004-04-14 devnull ok = gzip(nil, time(0), 0, &bout);
81 ff3adf60 2004-04-14 devnull Bterm(&bout);
82 ff3adf60 2004-04-14 devnull }else{
83 ff3adf60 2004-04-14 devnull ok = 1;
84 ff3adf60 2004-04-14 devnull for(i = 0; i < argc; i++)
85 ff3adf60 2004-04-14 devnull ok &= gzipf(argv[i], stdout);
86 ff3adf60 2004-04-14 devnull }
87 ff3adf60 2004-04-14 devnull exits(ok ? nil: "errors");
88 ff3adf60 2004-04-14 devnull }
89 ff3adf60 2004-04-14 devnull
90 ff3adf60 2004-04-14 devnull static int
91 ff3adf60 2004-04-14 devnull gzipf(char *file, int stdout)
92 ff3adf60 2004-04-14 devnull {
93 ff3adf60 2004-04-14 devnull Dir *dir;
94 ff3adf60 2004-04-14 devnull char ofile[256], *f, *s;
95 ff3adf60 2004-04-14 devnull int ifd, ofd, ok;
96 ff3adf60 2004-04-14 devnull
97 ff3adf60 2004-04-14 devnull ifd = open(file, OREAD);
98 ff3adf60 2004-04-14 devnull if(ifd < 0){
99 ff3adf60 2004-04-14 devnull fprint(2, "gzip: can't open %s: %r\n", file);
100 ff3adf60 2004-04-14 devnull return 0;
101 ff3adf60 2004-04-14 devnull }
102 ff3adf60 2004-04-14 devnull dir = dirfstat(ifd);
103 ff3adf60 2004-04-14 devnull if(dir == nil){
104 ff3adf60 2004-04-14 devnull fprint(2, "gzip: can't stat %s: %r\n", file);
105 ff3adf60 2004-04-14 devnull close(ifd);
106 ff3adf60 2004-04-14 devnull return 0;
107 ff3adf60 2004-04-14 devnull }
108 ff3adf60 2004-04-14 devnull if(dir->mode & DMDIR){
109 ff3adf60 2004-04-14 devnull fprint(2, "gzip: can't compress a directory\n");
110 ff3adf60 2004-04-14 devnull close(ifd);
111 ff3adf60 2004-04-14 devnull free(dir);
112 ff3adf60 2004-04-14 devnull return 0;
113 ff3adf60 2004-04-14 devnull }
114 ff3adf60 2004-04-14 devnull
115 ff3adf60 2004-04-14 devnull if(stdout){
116 ff3adf60 2004-04-14 devnull ofd = 1;
117 ff3adf60 2004-04-14 devnull strcpy(ofile, "<stdout>");
118 ff3adf60 2004-04-14 devnull }else{
119 ff3adf60 2004-04-14 devnull f = strrchr(file, '/');
120 ff3adf60 2004-04-14 devnull if(f != nil)
121 ff3adf60 2004-04-14 devnull f++;
122 ff3adf60 2004-04-14 devnull else
123 ff3adf60 2004-04-14 devnull f = file;
124 ff3adf60 2004-04-14 devnull s = strrchr(f, '.');
125 ff3adf60 2004-04-14 devnull if(s != nil && s != ofile && strcmp(s, ".tar") == 0){
126 ff3adf60 2004-04-14 devnull *s = '\0';
127 ff3adf60 2004-04-14 devnull snprint(ofile, sizeof(ofile), "%s.tgz", f);
128 ff3adf60 2004-04-14 devnull }else
129 ff3adf60 2004-04-14 devnull snprint(ofile, sizeof(ofile), "%s.gz", f);
130 ff3adf60 2004-04-14 devnull ofd = create(ofile, OWRITE, 0666);
131 ff3adf60 2004-04-14 devnull if(ofd < 0){
132 ff3adf60 2004-04-14 devnull fprint(2, "gzip: can't open %s: %r\n", ofile);
133 ff3adf60 2004-04-14 devnull close(ifd);
134 ff3adf60 2004-04-14 devnull return 0;
135 ff3adf60 2004-04-14 devnull }
136 ff3adf60 2004-04-14 devnull }
137 ff3adf60 2004-04-14 devnull
138 ff3adf60 2004-04-14 devnull if(verbose)
139 ff3adf60 2004-04-14 devnull fprint(2, "compressing %s to %s\n", file, ofile);
140 ff3adf60 2004-04-14 devnull
141 ff3adf60 2004-04-14 devnull Binit(&bout, ofd, OWRITE);
142 ff3adf60 2004-04-14 devnull ok = gzip(file, dir->mtime, ifd, &bout);
143 ff3adf60 2004-04-14 devnull if(!ok || Bflush(&bout) < 0){
144 ff3adf60 2004-04-14 devnull fprint(2, "gzip: error writing %s: %r\n", ofile);
145 ff3adf60 2004-04-14 devnull if(!stdout)
146 ff3adf60 2004-04-14 devnull remove(ofile);
147 ff3adf60 2004-04-14 devnull }
148 ff3adf60 2004-04-14 devnull Bterm(&bout);
149 ff3adf60 2004-04-14 devnull free(dir);
150 ff3adf60 2004-04-14 devnull close(ifd);
151 ff3adf60 2004-04-14 devnull close(ofd);
152 ff3adf60 2004-04-14 devnull return ok;
153 ff3adf60 2004-04-14 devnull }
154 ff3adf60 2004-04-14 devnull
155 ff3adf60 2004-04-14 devnull static int
156 ff3adf60 2004-04-14 devnull gzip(char *file, long mtime, int ifd, Biobuf *bout)
157 ff3adf60 2004-04-14 devnull {
158 ff3adf60 2004-04-14 devnull int flags, err;
159 ff3adf60 2004-04-14 devnull
160 ff3adf60 2004-04-14 devnull flags = 0;
161 ff3adf60 2004-04-14 devnull Bputc(bout, GZMAGIC1);
162 ff3adf60 2004-04-14 devnull Bputc(bout, GZMAGIC2);
163 ff3adf60 2004-04-14 devnull Bputc(bout, GZDEFLATE);
164 ff3adf60 2004-04-14 devnull
165 ff3adf60 2004-04-14 devnull if(file != nil)
166 ff3adf60 2004-04-14 devnull flags |= GZFNAME;
167 ff3adf60 2004-04-14 devnull Bputc(bout, flags);
168 ff3adf60 2004-04-14 devnull
169 ff3adf60 2004-04-14 devnull Bputc(bout, mtime);
170 ff3adf60 2004-04-14 devnull Bputc(bout, mtime>>8);
171 ff3adf60 2004-04-14 devnull Bputc(bout, mtime>>16);
172 ff3adf60 2004-04-14 devnull Bputc(bout, mtime>>24);
173 ff3adf60 2004-04-14 devnull
174 ff3adf60 2004-04-14 devnull Bputc(bout, 0);
175 ff3adf60 2004-04-14 devnull Bputc(bout, GZOSINFERNO);
176 ff3adf60 2004-04-14 devnull
177 ff3adf60 2004-04-14 devnull if(flags & GZFNAME)
178 ff3adf60 2004-04-14 devnull Bwrite(bout, file, strlen(file)+1);
179 ff3adf60 2004-04-14 devnull
180 ff3adf60 2004-04-14 devnull crc = 0;
181 ff3adf60 2004-04-14 devnull eof = 0;
182 ff3adf60 2004-04-14 devnull totr = 0;
183 3ca675a5 2006-04-20 devnull err = deflate(bout, gzwrite, (void*)(uintptr)ifd, crcread, level, debug);
184 ff3adf60 2004-04-14 devnull if(err != FlateOk){
185 ff3adf60 2004-04-14 devnull fprint(2, "gzip: deflate failed: %s\n", flateerr(err));
186 ff3adf60 2004-04-14 devnull return 0;
187 ff3adf60 2004-04-14 devnull }
188 ff3adf60 2004-04-14 devnull
189 ff3adf60 2004-04-14 devnull Bputc(bout, crc);
190 ff3adf60 2004-04-14 devnull Bputc(bout, crc>>8);
191 ff3adf60 2004-04-14 devnull Bputc(bout, crc>>16);
192 ff3adf60 2004-04-14 devnull Bputc(bout, crc>>24);
193 ff3adf60 2004-04-14 devnull
194 ff3adf60 2004-04-14 devnull Bputc(bout, totr);
195 ff3adf60 2004-04-14 devnull Bputc(bout, totr>>8);
196 ff3adf60 2004-04-14 devnull Bputc(bout, totr>>16);
197 ff3adf60 2004-04-14 devnull Bputc(bout, totr>>24);
198 ff3adf60 2004-04-14 devnull
199 ff3adf60 2004-04-14 devnull return 1;
200 ff3adf60 2004-04-14 devnull }
201 ff3adf60 2004-04-14 devnull
202 ff3adf60 2004-04-14 devnull static int
203 ff3adf60 2004-04-14 devnull crcread(void *fd, void *buf, int n)
204 ff3adf60 2004-04-14 devnull {
205 ff3adf60 2004-04-14 devnull int nr, m;
206 ff3adf60 2004-04-14 devnull
207 ff3adf60 2004-04-14 devnull nr = 0;
208 ff3adf60 2004-04-14 devnull for(; !eof && n > 0; n -= m){
209 3ca675a5 2006-04-20 devnull m = read((int)(uintptr)fd, (char*)buf+nr, n);
210 ff3adf60 2004-04-14 devnull if(m <= 0){
211 ff3adf60 2004-04-14 devnull eof = 1;
212 ff3adf60 2004-04-14 devnull if(m < 0)
213 ff3adf60 2004-04-14 devnull return -1;
214 ff3adf60 2004-04-14 devnull break;
215 ff3adf60 2004-04-14 devnull }
216 ff3adf60 2004-04-14 devnull nr += m;
217 ff3adf60 2004-04-14 devnull }
218 ff3adf60 2004-04-14 devnull crc = blockcrc(crctab, crc, buf, nr);
219 ff3adf60 2004-04-14 devnull totr += nr;
220 ff3adf60 2004-04-14 devnull return nr;
221 ff3adf60 2004-04-14 devnull }
222 ff3adf60 2004-04-14 devnull
223 ff3adf60 2004-04-14 devnull static int
224 ff3adf60 2004-04-14 devnull gzwrite(void *bout, void *buf, int n)
225 ff3adf60 2004-04-14 devnull {
226 ff3adf60 2004-04-14 devnull if(n != Bwrite(bout, buf, n)){
227 ff3adf60 2004-04-14 devnull eof = 1;
228 ff3adf60 2004-04-14 devnull return -1;
229 ff3adf60 2004-04-14 devnull }
230 ff3adf60 2004-04-14 devnull return n;
231 ff3adf60 2004-04-14 devnull }