int ey_zlib_stream_unpack(ey_zlib_t z, char *i_buf, size_t i_len, ey_zlib_callback cb, void *arg) { if(!z || !cb || !i_buf || !i_len) { zlib_debug(debug_zlib_basic, "bad parameter in ey_zlib_stream_unpack\n"); return -1; } ey_zlib_private_t *zp = (ey_zlib_private_t*)z; ey_zlib_format_t format = zp->format; zp->err_msg = NULL; if(format == EY_ZLIB_FORMAT_DEFLATE_UNPACK) { if(do_inflate(zp, i_buf, i_len, cb, arg)) { zlib_debug(debug_zlib_basic, "find error in inflate: %s\n", zp->err_msg?zp->err_msg:"unkown error"); return -1; } zlib_debug(debug_zlib_basic, "inflate %d bytes successfully\n", i_len); } else if(format == EY_ZLIB_FORMAT_GZIP_UNPACK) { if(do_gunzip(zp, i_buf, i_len, cb, arg)) { zlib_debug(debug_zlib_basic, "find error in gunzip: %s\n", zp->err_msg?zp->err_msg:"unkown error"); return -1; } zlib_debug(debug_zlib_basic, "gunzip %d bytes successfully\n", i_len); } else { assert(0); } return 0; }
static ssize_t rz_read(file_t fd, void * buffer, size_t size) { rdfh_t * rd = (rdfh_t *)fd; int err; if (!size) { return 0; } if (!buffer) { return -1; } if (!rd || rd != cur_rd) { return -1; } if (!rd->udata) { if (rd->cdata == cached_shadow) { /* SDDEBUG("[rz] : Using cached buffer @%p shadow:%p]\n", */ /* cached_addr,cached_shadow); */ rd->udata = cached_addr; } else { rd->udata = malloc(rd->ulen); if (!rd->udata) { SDERROR("[rz] : malloc error (%d bytes)\n", rd->ulen); return -1; } if (cached_addr) { /* SDDEBUG("[rz] : Free old cached buffer @%p shadow:%p]\n", */ /* cached_addr,cached_shadow); */ free (cached_addr); } cached_addr = rd->udata; cached_shadow = rd->cdata; /* SDDEBUG("[rz] : New cached buffer @%p shadow:%p]\n", */ /* cached_addr,cached_shadow); */ err = do_inflate(rd->udata, rd->ulen, rd->cdata, rd->clen); if (err) { free(rd->udata); if (rd->udata == cached_addr) { cached_addr = 0; cached_shadow = 0; } rd->udata = 0; return -1; } } } err = rd->ulen - rd->uptr; if (err > size) { err = size; } memcpy(buffer, rd->udata + rd->uptr, err); rd->uptr += err; /* SDDEBUG("[rz] : read [%p,%p,%d,%d]\n", rd, buffer,size,err); */ return err; }
/* Callback which is passed blocks of the response body. */ static int gz_reader(void *ud, const char *buf, size_t len) { ne_decompress *ctx = ud; const char *zbuf; size_t count; const char *hdr; if (len == 0) { /* End of response: */ switch (ctx->state) { case NE_Z_BEFORE_DATA: hdr = ne_get_response_header(ctx->request, "Content-Encoding"); if (hdr && strcasecmp(hdr, "gzip") == 0) { /* response was truncated: return error. */ break; } /* else, fall through */ case NE_Z_FINISHED: /* complete gzip response */ case NE_Z_PASSTHROUGH: /* complete uncompressed response */ return ctx->reader(ctx->userdata, buf, 0); default: /* invalid state: truncated response. */ break; } /* else: truncated response, fail. */ ne_set_error(ctx->session, "Compressed response was truncated"); return NE_ERROR; } switch (ctx->state) { case NE_Z_PASSTHROUGH: /* move along there. */ return ctx->reader(ctx->userdata, buf, len); case NE_Z_FINISHED: /* Could argue for tolerance, and ignoring trailing content; * but it could mean something more serious. */ if (len > 0) { ne_set_error(ctx->session, "Unexpected content received after compressed stream"); return NE_ERROR; } break; case NE_Z_BEFORE_DATA: /* work out whether this is a compressed response or not. */ hdr = ne_get_response_header(ctx->request, "Content-Encoding"); if (hdr && strcasecmp(hdr, "gzip") == 0) { int ret; NE_DEBUG(NE_DBG_HTTP, "compress: got gzipped stream.\n"); /* inflateInit2() works here where inflateInit() doesn't. */ ret = inflateInit2(&ctx->zstr, -MAX_WBITS); if (ret != Z_OK) { set_zlib_error(ctx, _("Could not initialize zlib"), ret); return -1; } ctx->zstrinit = 1; } else { /* No Content-Encoding header: pass it on. TODO: we could * hack it and register the real callback now. But that * would require add_resp_body_rdr to have defined * ordering semantics etc etc */ ctx->state = NE_Z_PASSTHROUGH; return ctx->reader(ctx->userdata, buf, len); } ctx->state = NE_Z_IN_HEADER; /* FALLTHROUGH */ case NE_Z_IN_HEADER: /* copy as many bytes as possible into the buffer. */ if (len + ctx->hdrcount > 10) { count = 10 - ctx->hdrcount; } else { count = len; } memcpy(ctx->header + ctx->hdrcount, buf, count); ctx->hdrcount += count; /* have we got the full header yet? */ if (ctx->hdrcount != 10) { return 0; } buf += count; len -= count; switch (parse_header(ctx)) { case HDR_EXTENDED: if (len == 0) return 0; break; case HDR_ERROR: return NE_ERROR; case HDR_DONE: if (len > 0) { return do_inflate(ctx, buf, len); } break; } /* FALLTHROUGH */ case NE_Z_POST_HEADER: /* eating the filename string. */ zbuf = memchr(buf, '\0', len); if (zbuf == NULL) { /* not found it yet. */ return 0; } NE_DEBUG(NE_DBG_HTTP, "compresss: skipped %" NE_FMT_SIZE_T " header bytes.\n", zbuf - buf); /* found end of string. */ len -= (1 + zbuf - buf); buf = zbuf + 1; ctx->state = NE_Z_INFLATING; if (len == 0) { /* end of string was at end of buffer. */ return 0; } /* FALLTHROUGH */ case NE_Z_INFLATING: return do_inflate(ctx, buf, len); case NE_Z_AFTER_DATA: return process_footer(ctx, (unsigned char *)buf, len); } return 0; }
static int optional_inflate (scs_t *ctx, scs_keyset_t *ks) { return !ks->comp ? 0 : do_inflate(ctx); }
int ploop_balloon_change_size(const char *device, int balloonfd, off_t new_size) { int fd = -1; int ret; off_t old_size; __u32 dev_start; /* /sys/block/ploop0/ploop0p1/start */ __u32 n_free_blocks; __u32 freezed_a_h; struct ploop_balloon_ctl b_ctl; struct stat st; struct pfiemap *pfiemap = NULL; struct freemap *freemap = NULL; struct freemap *rangemap = NULL; struct relocmap *relocmap = NULL; struct ploop_freeblks_ctl *freeblks = NULL; struct ploop_relocblks_ctl *relocblks = NULL; __u32 *reverse_map = NULL; __u32 reverse_map_len; int top_level; struct delta delta = { .fd = -1 }; int entries_used; int drop_state = 0; if (fstat(balloonfd, &st)) { ploop_err(errno, "Can't get balloon file size"); return SYSEXIT_FSTAT; } old_size = st.st_size; new_size = (S2B(new_size) + st.st_blksize - 1) & ~(st.st_blksize - 1); ploop_log(0, "Changing balloon size old_size=%ld new_size=%ld", (long)old_size, (long)new_size); pfiemap = fiemap_alloc(128); freemap = freemap_alloc(128); rangemap = freemap_alloc(128); relocmap = relocmap_alloc(128); if (!pfiemap || !freemap || !rangemap || !relocmap) { ret = SYSEXIT_MALLOC; goto err; } fd = open_device(device); if (fd == -1) { ret = SYSEXIT_OPEN; goto err; } memset(&b_ctl, 0, sizeof(b_ctl)); if (old_size < new_size) b_ctl.inflate = 1; ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl); if (ret) goto err; drop_state = 1; if (old_size >= new_size) { ret = do_truncate(balloonfd, b_ctl.mntn_type, old_size, new_size); goto err; } if (dev_num2dev_start(device, st.st_dev, &dev_start)) { ploop_err(0, "Can't find out offset from start of ploop " "device (%s) to start of partition", device); ret = SYSEXIT_SYSFS; goto err; } ret = open_top_delta(device, &delta, &top_level); if (ret) goto err; ret = do_inflate(balloonfd, b_ctl.mntn_type, old_size, &new_size, &drop_state); if (ret) goto err; reverse_map_len = delta.l2_size + delta.l2_size; reverse_map = alloc_reverse_map(reverse_map_len); if (reverse_map == NULL) { ret = SYSEXIT_MALLOC; goto err; } ret = fiemap_get(balloonfd, S2B(dev_start), old_size, new_size, &pfiemap); if (ret) goto err; fiemap_adjust(pfiemap, delta.blocksize); ret = fiemap_build_rmap(pfiemap, reverse_map, reverse_map_len, &delta); if (ret) goto err; ret = rmap2freemap(reverse_map, 0, reverse_map_len, &freemap, &entries_used); if (ret) goto err; if (entries_used == 0) { drop_state = 1; ploop_log(0, "No unused cluster blocks found"); goto out; } ret = freemap2freeblks(freemap, top_level, &freeblks, &n_free_blocks); if (ret) goto err; ret = ioctl_device(fd, PLOOP_IOC_FREEBLKS, freeblks); if (ret) goto err; freezed_a_h = freeblks->alloc_head; if (freezed_a_h > reverse_map_len) { ploop_err(0, "Image corrupted: a_h=%u > rlen=%u", freezed_a_h, reverse_map_len); ret = SYSEXIT_PLOOPFMT; goto err; } ret = range_build(freezed_a_h, n_free_blocks, reverse_map, reverse_map_len, &delta, freemap, &rangemap, &relocmap); if (ret) goto err; ret = relocmap2relocblks(relocmap, top_level, freezed_a_h, n_free_blocks, &relocblks); if (ret) goto err; ret = ioctl_device(fd, PLOOP_IOC_RELOCBLKS, relocblks); if (ret) goto err; ploop_log(0, "TRUNCATED: %u cluster-blocks (%llu bytes)", relocblks->alloc_head, (unsigned long long)(relocblks->alloc_head * S2B(delta.blocksize))); out: ret = 0; err: if (drop_state) { memset(&b_ctl, 0, sizeof(b_ctl)); (void)ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl); } if (fd != -1) close(fd); free(pfiemap); free(freemap); free(rangemap); free(relocmap); free(reverse_map); free(freeblks); free(relocblks); if (delta.fd != -1) close_delta(&delta); return ret; } int ploop_balloon_get_state(const char *device, __u32 *state) { int fd, ret; struct ploop_balloon_ctl b_ctl; fd = open_device(device); if (fd == -1) return SYSEXIT_OPEN; bzero(&b_ctl, sizeof(b_ctl)); b_ctl.keep_intact = 1; ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl); if (ret) goto err; *state = b_ctl.mntn_type; err: close(fd); return ret; }
int transfer_gzfile_inl(struct asfd *asfd, struct sbuf *sb, const char *path, BFILE *bfd, uint64_t *rcvd, uint64_t *sent, const char *encpassword, int enccompressed, struct cntr *cntr, char **metadata) { int quit=0; int ret=-1; uint8_t out[ZCHUNK]; int doutlen=0; //uint8_t doutbuf[1000+EVP_MAX_BLOCK_LENGTH]; uint8_t doutbuf[ZCHUNK-EVP_MAX_BLOCK_LENGTH]; struct iobuf *rbuf=asfd->rbuf; z_stream zstrm; EVP_CIPHER_CTX *enc_ctx=NULL; // Checksum stuff //MD5_CTX md5; //uint8_t checksum[MD5_DIGEST_LENGTH]; #ifdef HAVE_WIN32 if(sb && sb->path.cmd==CMD_EFS_FILE) return transfer_efs_in(asfd, bfd, rcvd, sent, cntr); #endif //if(!MD5_Init(&md5)) //{ // logp("MD5_Init() failed"); // return -1; //} zstrm.zalloc=Z_NULL; zstrm.zfree=Z_NULL; zstrm.opaque=Z_NULL; zstrm.avail_in=0; zstrm.next_in=Z_NULL; if(inflateInit2(&zstrm, (15+16))) { logp("unable to init inflate\n"); return -1; } if(encpassword && !(enc_ctx=enc_setup(0, encpassword))) { inflateEnd(&zstrm); return -1; } while(!quit) { iobuf_free_content(rbuf); if(asfd->read(asfd)) { if(enc_ctx) { EVP_CIPHER_CTX_cleanup(enc_ctx); free(enc_ctx); } inflateEnd(&zstrm); return -1; } (*rcvd)+=rbuf->len; //logp("transfer in: %c:%s\n", rbuf->cmd, rbuf->buf); switch(rbuf->cmd) { case CMD_APPEND: // append if(!bfd && !metadata) { logp("given append, but no file or metadata to write to\n"); asfd->write_str(asfd, CMD_ERROR, "append with no file or metadata"); quit++; ret=-1; } else { size_t lentouse; uint8_t *buftouse=NULL; /* if(!MD5_Update(&md5, rbuf->buf, rbuf->len)) { logp("MD5 update enc error\n"); quit++; ret=-1; break; } */ // If doing decryption, it needs // to be done before uncompressing. if(enc_ctx) { // updating our checksum needs to // be done first /* if(!MD5_Update(&md5, rbuf->buf, rbuf->len)) { logp("MD5 update enc error\n"); quit++; ret=-1; break; } else */ if(!EVP_CipherUpdate(enc_ctx, doutbuf, &doutlen, (uint8_t *)rbuf->buf, rbuf->len)) { logp("Decryption error\n"); quit++; ret=-1; break; } if(!doutlen) break; lentouse=(size_t)doutlen; buftouse=doutbuf; } else { lentouse=rbuf->len; buftouse=(uint8_t *)rbuf->buf; } //logp("want to write: %d\n", zstrm.avail_in); if(do_inflate(asfd, &zstrm, bfd, out, buftouse, lentouse, metadata, encpassword, enccompressed, sent)) { ret=-1; quit++; break; } } break; case CMD_END_FILE: // finish up if(enc_ctx) { if(!EVP_CipherFinal_ex(enc_ctx, doutbuf, &doutlen)) { logp("Decryption failure at the end.\n"); ret=-1; quit++; break; } if(doutlen && do_inflate(asfd, &zstrm, bfd, out, doutbuf, (size_t)doutlen, metadata, encpassword, enccompressed, sent)) { ret=-1; quit++; break; } } /* if(MD5_Final(checksum, &md5)) { char *oldsum=NULL; const char *newsum=NULL; if((oldsum=strchr(buf, ':'))) { oldsum++; newsum=bytes_to_md5str(checksum); // log if the checksum differed if(strcmp(newsum, oldsum)) logw(asfd, cntr, "md5sum for '%s' did not match! (%s!=%s)\n", path, newsum, oldsum); } } else { logp("MD5_Final() failed\n"); } */ quit++; ret=0; break; case CMD_MESSAGE: case CMD_WARNING: log_recvd(rbuf, cntr, 0); break; default: iobuf_log_unexpected(rbuf, __func__); quit++; ret=-1; break; } } inflateEnd(&zstrm); if(enc_ctx) { EVP_CIPHER_CTX_cleanup(enc_ctx); free(enc_ctx); } iobuf_free_content(rbuf); if(ret) logp("transfer file returning: %d\n", ret); return ret; }
int transfer_gzfile_in(struct sbuf *sb, const char *path, BFILE *bfd, FILE *fp, unsigned long long *rcvd, unsigned long long *sent, const char *encpassword, int enccompressed, struct cntr *cntr, char **metadata) { char cmd; char *buf=NULL; size_t len=0; int quit=0; int ret=-1; unsigned char out[ZCHUNK]; size_t doutlen=0; //unsigned char doutbuf[1000+EVP_MAX_BLOCK_LENGTH]; unsigned char doutbuf[ZCHUNK-EVP_MAX_BLOCK_LENGTH]; z_stream zstrm; EVP_CIPHER_CTX *enc_ctx=NULL; // Checksum stuff //MD5_CTX md5; //unsigned char checksum[MD5_DIGEST_LENGTH+1]; //logp("in transfer_gzfile_in\n"); #ifdef HAVE_WIN32 if(sb && sb->cmd==CMD_EFS_FILE) return transfer_efs_in(bfd, rcvd, sent, cntr); #endif //if(!MD5_Init(&md5)) //{ // logp("MD5_Init() failed"); // return -1; //} zstrm.zalloc=Z_NULL; zstrm.zfree=Z_NULL; zstrm.opaque=Z_NULL; zstrm.avail_in=0; zstrm.next_in=Z_NULL; if(inflateInit2(&zstrm, (15+16))) { logp("unable to init inflate\n"); return -1; } if(encpassword && !(enc_ctx=enc_setup(0, encpassword))) { inflateEnd(&zstrm); return -1; } while(!quit) { if(async_read(&cmd, &buf, &len)) { if(enc_ctx) { EVP_CIPHER_CTX_cleanup(enc_ctx); free(enc_ctx); } inflateEnd(&zstrm); return -1; } (*rcvd)+=len; //logp("transfer in: %c:%s\n", cmd, buf); switch(cmd) { case CMD_APPEND: // append if(!fp && !bfd && !metadata) { logp("given append, but no file or metadata to write to\n"); async_write_str(CMD_ERROR, "append with no file or metadata"); quit++; ret=-1; } else { size_t lentouse; unsigned char *buftouse=NULL; /* if(!MD5_Update(&md5, buf, len)) { logp("MD5 update enc error\n"); quit++; ret=-1; break; } */ // If doing decryption, it needs // to be done before uncompressing. if(enc_ctx) { // updating our checksum needs to // be done first /* if(!MD5_Update(&md5, buf, len)) { logp("MD5 update enc error\n"); quit++; ret=-1; break; } else */ if(!EVP_CipherUpdate(enc_ctx, doutbuf, (int *)&doutlen, (unsigned char *)buf, len)) { logp("Decryption error\n"); quit++; ret=-1; break; } if(!doutlen) break; lentouse=doutlen; buftouse=doutbuf; } else { lentouse=len; buftouse=(unsigned char *)buf; } //logp("want to write: %d\n", zstrm.avail_in); if(do_inflate(&zstrm, bfd, fp, out, buftouse, lentouse, metadata, encpassword, enccompressed, sent)) { ret=-1; quit++; break; } } break; case CMD_END_FILE: // finish up if(enc_ctx) { if(!EVP_CipherFinal_ex(enc_ctx, doutbuf, (int *)&doutlen)) { logp("Decryption failure at the end.\n"); ret=-1; quit++; break; } if(doutlen && do_inflate(&zstrm, bfd, fp, out, doutbuf, doutlen, metadata, encpassword, enccompressed, sent)) { ret=-1; quit++; break; } } /* if(MD5_Final(checksum, &md5)) { char *oldsum=NULL; const char *newsum=NULL; if((oldsum=strchr(buf, ':'))) { oldsum++; newsum=get_checksum_str(checksum); // log if the checksum differed if(strcmp(newsum, oldsum)) logw(cntr, "md5sum for '%s' did not match! (%s!=%s)\n", path, newsum, oldsum); } } else { logp("MD5_Final() failed\n"); } */ quit++; ret=0; break; case CMD_WARNING: logp("WARNING: %s\n", buf); do_filecounter(cntr, cmd, 0); break; default: logp("unknown append cmd: %c\n", cmd); quit++; ret=-1; break; } if(buf) free(buf); buf=NULL; } inflateEnd(&zstrm); if(enc_ctx) { EVP_CIPHER_CTX_cleanup(enc_ctx); free(enc_ctx); } if(ret) logp("transfer file returning: %d\n", ret); return ret; }
int transfer_gzfile_in(struct asfd *asfd, const char *path, BFILE *bfd, uint64_t *rcvd, uint64_t *sent, struct cntr *cntr) { int quit=0; int ret=-1; uint8_t out[ZCHUNK]; struct iobuf *rbuf=asfd->rbuf; z_stream zstrm; zstrm.zalloc=Z_NULL; zstrm.zfree=Z_NULL; zstrm.opaque=Z_NULL; zstrm.avail_in=0; zstrm.next_in=Z_NULL; if(inflateInit2(&zstrm, (15+16))) { logp("unable to init inflate\n"); goto end; } while(!quit) { iobuf_free_content(rbuf); if(asfd->read(asfd)) goto end_inflate; (*rcvd)+=rbuf->len; //logp("transfer in: %c:%s\n", rbuf->cmd, rbuf->buf); switch(rbuf->cmd) { case CMD_APPEND: // append if(!bfd) { logp("given append, but no file to write to\n"); asfd->write_str(asfd, CMD_ERROR, "append with no file"); goto end_inflate; } else { if(do_inflate(asfd, &zstrm, bfd, out, sent)) goto end_inflate; } break; case CMD_END_FILE: // finish up goto end_ok; case CMD_MESSAGE: case CMD_WARNING: { struct cntr *cntr=NULL; log_recvd(rbuf, cntr, 0); break; } default: iobuf_log_unexpected(rbuf, __func__); goto end_inflate; } } end_ok: ret=0; end_inflate: inflateEnd(&zstrm); end: if(ret) logp("transfer file returning: %d\n", ret); iobuf_free_content(rbuf); return ret; }