1 #include "burp.h"
2 #include "asfd.h"
3 #include "async.h"
4 #include "bfile.h"
5 #include "cmd.h"
6 #include "fzp.h"
7 #include "iobuf.h"
8 #include "log.h"
9 #include "msg.h"
10
send_msg_fzp(struct fzp * fzp,enum cmd cmd,const char * buf,size_t s)11 int send_msg_fzp(struct fzp *fzp, enum cmd cmd, const char *buf, size_t s)
12 {
13 if(fzp_printf(fzp, "%c%04X", cmd, (unsigned int)s)!=5
14 || fzp_write(fzp, buf, s)!=s
15 || fzp_printf(fzp, "\n")!=1)
16 {
17 logp("Unable to write message to file: %s\n", strerror(errno));
18 return -1;
19 }
20 return 0;
21 }
22
do_write(struct asfd * asfd,struct BFILE * bfd,uint8_t * out,size_t outlen,uint64_t * sent)23 static int do_write(struct asfd *asfd, struct BFILE *bfd,
24 uint8_t *out, size_t outlen, uint64_t *sent)
25 {
26 int ret=0;
27 if((ret=bfd->write(bfd, out, outlen))<=0)
28 {
29 logp("%s: error when appending %lu: %d\n",
30 __func__, (unsigned long)outlen, ret);
31 asfd->write_str(asfd, CMD_ERROR, "write failed");
32 return -1;
33 }
34 *sent+=outlen;
35 return 0;
36 }
37
do_inflate(struct asfd * asfd,z_stream * zstrm,struct BFILE * bfd,uint8_t * out,uint64_t * sent)38 static int do_inflate(struct asfd *asfd, z_stream *zstrm, struct BFILE *bfd,
39 uint8_t *out, uint64_t *sent)
40 {
41 int zret=Z_OK;
42 unsigned have=0;
43 struct iobuf *rbuf=asfd->rbuf;
44
45 zstrm->avail_in=rbuf->len;
46 zstrm->next_in=(uint8_t *)rbuf->buf;
47
48 do
49 {
50 zstrm->avail_out=ZCHUNK;
51 zstrm->next_out=out;
52 zret=inflate(zstrm, Z_NO_FLUSH);
53 switch(zret)
54 {
55 case Z_NEED_DICT:
56 zret=Z_DATA_ERROR;
57 case Z_DATA_ERROR:
58 case Z_MEM_ERROR:
59 logp("zstrm inflate error: %d\n", zret);
60 return -1;
61 }
62 have=ZCHUNK-zstrm->avail_out;
63 if(!have) continue;
64
65 if(do_write(asfd, bfd, out, have, sent))
66 return -1;
67 } while(!zstrm->avail_out);
68 return 0;
69 }
70
transfer_gzfile_in(struct asfd * asfd,struct BFILE * bfd,uint64_t * rcvd,uint64_t * sent)71 int transfer_gzfile_in(struct asfd *asfd, struct BFILE *bfd,
72 uint64_t *rcvd, uint64_t *sent)
73 {
74 int quit=0;
75 int ret=-1;
76 uint8_t out[ZCHUNK];
77 struct iobuf *rbuf=asfd->rbuf;
78 z_stream zstrm;
79
80 zstrm.zalloc=Z_NULL;
81 zstrm.zfree=Z_NULL;
82 zstrm.opaque=Z_NULL;
83 zstrm.avail_in=0;
84 zstrm.next_in=Z_NULL;
85
86 if(inflateInit2(&zstrm, (15+16)))
87 {
88 logp("unable to init inflate\n");
89 goto end;
90 }
91
92 while(!quit)
93 {
94 iobuf_free_content(rbuf);
95 if(asfd->read(asfd)) goto end_inflate;
96 (*rcvd)+=rbuf->len;
97
98 //logp("transfer in: %s\n", iobuf_to_printable(rbuf));
99 switch(rbuf->cmd)
100 {
101 case CMD_APPEND: // append
102 if(!bfd)
103 {
104 logp("given append, but no file to write to\n");
105 asfd->write_str(asfd, CMD_ERROR,
106 "append with no file");
107 goto end_inflate;
108 }
109 else
110 {
111 if(do_inflate(asfd, &zstrm,
112 bfd, out, sent))
113 goto end_inflate;
114 }
115 break;
116 case CMD_END_FILE: // finish up
117 goto end_ok;
118 case CMD_MESSAGE:
119 case CMD_WARNING:
120 {
121 struct cntr *cntr=NULL;
122 log_recvd(rbuf, cntr, 0);
123 break;
124 }
125 default:
126 iobuf_log_unexpected(rbuf, __func__);
127 goto end_inflate;
128 }
129 }
130
131 end_ok:
132 ret=0;
133 end_inflate:
134 inflateEnd(&zstrm);
135 end:
136 if(ret) logp("transfer file returning: %d\n", ret);
137 iobuf_free_content(rbuf);
138 return ret;
139 }
140