]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/hgfs/zip.c
hgfs: honor x-bit in manifest
[plan9front.git] / sys / src / cmd / hgfs / zip.c
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include "dat.h"
5 #include "fns.h"
6
7 #include <flate.h>
8
9 struct zbuf {
10         int     fd;
11         int     len;
12
13         uchar   *b, *p, *e;
14 };
15
16 static int
17 zwrite(void *a, void *p, int n)
18 {
19         int *ofd = a;
20
21         if(write(*ofd, p, n) != n)
22                 return -1;
23         return n;
24 }
25
26 static int
27 zgetc(void *a)
28 {
29         struct zbuf *z = a;
30         int n;
31
32         for(;;){
33                 if(z->p < z->e)
34                         return *z->p++;
35                 if(z->len <= 0)
36                         return -1;
37                 if((n = BUFSZ) > z->len)
38                         n = z->len;
39                 if((n = read(z->fd, z->p = z->b, n)) <= 0)
40                         return -1;
41                 z->len -= n;
42                 z->e = z->p + n;
43         }
44 }
45
46 int
47 funzip(int ofd, int zfd, int len)
48 {
49         uchar buf[BUFSZ];
50         struct zbuf z;
51         int wlen, n;
52         uchar *p;
53
54         if(len == 0)
55                 return 0;
56
57         wlen = 0;
58         if((n = BUFSZ) > len)
59                 n = len;
60         if((n = read(zfd, p = buf, n)) <= 0)
61                 return -1;
62         len -= n;
63         switch(*p){
64         default:
65                 return -1;
66         case 'u':
67                 p++;
68                 n--;
69                 /* no break */
70         case '\0':
71                 while((n > 0) && (write(ofd, p, n) == n)){
72                         wlen += n;
73                         if(len <= 0)
74                                 break;
75                         if((n = BUFSZ) > len)
76                                 n = len;
77                         if((n = read(zfd, p = buf, n)) <= 0)
78                                 break;
79                         len -= n;
80                 }
81                 break;
82         case 'x':
83                 if(n < 2)
84                         return -1;
85                 z.fd = zfd;
86                 z.len = len;
87                 z.b = buf;
88                 z.p = p + 2;
89                 z.e = p + n;
90                 if((wlen = inflate(&ofd, zwrite, &z, zgetc)) < 0){
91                         werrstr("%s", flateerr(wlen));
92                         return -1;
93                 }
94                 break;
95         }
96         return wlen;
97 }