int zlib_inflate(struct asfd *asfd, const char *source_path, const char *dest_path, struct conf **confs) { int ret=-1; size_t b=0; uint8_t in[ZCHUNK]; struct fzp *src=NULL; struct fzp *dst=NULL; if(!(src=fzp_gzopen(source_path, "rb"))) { logw(asfd, confs, "could not gzopen %s in %s: %s\n", source_path, __func__, strerror(errno)); goto end; } if(!(dst=fzp_open(dest_path, "wb"))) { logw(asfd, confs, "could not open %s in %s: %s\n", dest_path, __func__, strerror(errno)); goto end; } while((b=fzp_read(src, in, ZCHUNK))>0) { if(fzp_write(dst, in, b)!=b) { logw(asfd, confs, "error when writing to %s\n", dest_path); goto end; } } if(!fzp_eof(src)) { logw(asfd, confs, "error while reading %s in %s\n", source_path, __func__); goto end; } if(fzp_close(&dst)) { logw(asfd, confs, "error when closing %s in %s: %s\n", dest_path, __func__, strerror(errno)); goto end; } ret=0; end: fzp_close(&src); fzp_close(&dst); return ret; }
int fzp_read_ensure(struct fzp *fzp, void *ptr, size_t nmemb, const char *func) { static int f; static int r; static size_t got; static int pass; for(r=0, got=0, pass=0; got!=nmemb; pass++) { r=fzp_read(fzp, ((char *)ptr)+got, nmemb-got); if(r>0) { got+=r; continue; } if(r<0) { pass_msg(nmemb, got, pass); logp("Error in %s, called from %s: %s\n", __func__, func, strerror(errno)); return -1; } f=fzp_eof(fzp); if(!f) continue; // Not yet end of file, keep trying. if(f>0) { // End of file. if(!got) return 1; pass_msg(nmemb, got, pass); logp("Error in %s, called from %s: %u bytes, eof\n", __func__, func, got); return -1; } else { pass_msg(nmemb, got, pass); logp("Error in %s by fzp_feof, called from %s: %s\n", __func__, func, strerror(errno)); return -1; } } return 0; }
static int verify_file(struct asfd *asfd, struct sbuf *sb, int patches, const char *best, uint64_t *bytes, struct cntr *cntr) { MD5_CTX md5; size_t b=0; const char *cp=NULL; const char *newsum=NULL; uint8_t in[ZCHUNK]; uint8_t checksum[MD5_DIGEST_LENGTH]; uint64_t cbytes=0; struct fzp *fzp=NULL; if(!(cp=strrchr(sb->endfile.buf, ':'))) { logw(asfd, cntr, "%s has no md5sum!\n", sb->protocol1->datapth.buf); return 0; } cp++; if(!MD5_Init(&md5)) { logp("MD5_Init() failed\n"); return -1; } if(patches || sb->path.cmd==CMD_ENC_FILE || sb->path.cmd==CMD_ENC_METADATA || sb->path.cmd==CMD_EFS_FILE || sb->path.cmd==CMD_ENC_VSS || (!patches && !dpth_protocol1_is_compressed(sb->compression, best))) fzp=fzp_open(best, "rb"); else fzp=fzp_gzopen(best, "rb"); if(!fzp) { logw(asfd, cntr, "could not open %s\n", best); return 0; } while((b=fzp_read(fzp, in, ZCHUNK))>0) { cbytes+=b; if(!MD5_Update(&md5, in, b)) { logp("MD5_Update() failed\n"); fzp_close(&fzp); return -1; } } if(!fzp_eof(fzp)) { logw(asfd, cntr, "error while reading %s\n", best); fzp_close(&fzp); return 0; } fzp_close(&fzp); if(!MD5_Final(checksum, &md5)) { logp("MD5_Final() failed\n"); return -1; } newsum=bytes_to_md5str(checksum); if(strcmp(newsum, cp)) { logp("%s %s\n", newsum, cp); logw(asfd, cntr, "md5sum for '%s (%s)' did not match!\n", sb->path.buf, sb->protocol1->datapth.buf); logp("md5sum for '%s (%s)' did not match!\n", sb->path.buf, sb->protocol1->datapth.buf); return 0; } *bytes+=cbytes; // Just send the file name to the client, so that it can show cntr. if(asfd->write(asfd, &sb->path)) return -1; return 0; }
/* * If the stream has no more data available, read some from F into * BUF, and let the stream use that. On return, SEEN_EOF is true if * the end of file has passed into the stream. */ rs_result rs_infilebuf_fill(rs_job_t *job, rs_buffers_t *buf, void *opaque) { int len=0; rs_filebuf_t *fb=(rs_filebuf_t *) opaque; struct cntr *cntr; int fd=fb->fd; cntr=fb->cntr; //logp("rs_infilebuf_fill\n"); /* This is only allowed if either the buf has no input buffer * yet, or that buffer could possibly be BUF. */ if(buf->next_in) { //logp("infilebuf avail_in %d buf_len %d\n", // buf->avail_in, fb->buf_len); if(buf->avail_in > fb->buf_len) { logp("buf->avail_in > fb->buf_len (%d > %d) in %s\n", buf->avail_in, fb->buf_len, __func__); return RS_IO_ERROR; } if(buf->next_in < fb->buf) { logp("buf->next_in < fb->buf in %s\n", __func__); return RS_IO_ERROR; } if(buf->next_in > fb->buf + fb->buf_len) { logp("buf->next_in > fb->buf + fb->buf_len in %s\n", __func__); return RS_IO_ERROR; } } else { if(buf->avail_in) { logp("buf->avail_in is %d in %s\n", buf->avail_in, __func__); return RS_IO_ERROR; } } if(buf->eof_in) return RS_DONE; if(buf->avail_in) /* Still some data remaining. Perhaps we should read anyhow? */ return RS_DONE; if(fd>=0) { static struct iobuf *rbuf=NULL; rbuf=fb->asfd->rbuf; if(fb->asfd->read(fb->asfd)) return RS_IO_ERROR; if(rbuf->cmd==CMD_APPEND) { //logp("got '%c' in fd infilebuf: %d\n", // CMD_APPEND, rbuf->len); memcpy(fb->buf, rbuf->buf, rbuf->len); len=rbuf->len; iobuf_free_content(rbuf); } else if(rbuf->cmd==CMD_END_FILE) { iobuf_free_content(rbuf); //logp("got %c in fd infilebuf\n", CMD_END_FILE); buf->eof_in=1; return RS_DONE; } else if(rbuf->cmd==CMD_WARNING) { logp("WARNING: %s\n", rbuf->buf); cntr_add(cntr, rbuf->cmd, 0); iobuf_free_content(rbuf); return RS_DONE; } else { iobuf_log_unexpected(rbuf, __func__); iobuf_free_content(rbuf); return RS_IO_ERROR; } } else if(fb->bfd) { if(fb->do_known_byte_count) { if(fb->data_len>0) { len=fb->bfd->read(fb->bfd, fb->buf, min(fb->buf_len, fb->data_len)); fb->data_len-=len; } else { // We have already read as much data as the VSS // header told us to, so set len=0 in order to // finish up. len=0; } } else len=fb->bfd->read(fb->bfd, fb->buf, fb->buf_len); if(len==0) { //logp("bread: eof\n"); buf->eof_in=1; return RS_DONE; } else if(len<0) { logp("rs_infilebuf_fill: error in bread\n"); return RS_IO_ERROR; } //logp("bread: ok: %d\n", len); fb->bytes+=len; if(!MD5_Update(&(fb->md5), fb->buf, len)) { logp("rs_infilebuf_fill: MD5_Update() failed\n"); return RS_IO_ERROR; } } else if(fb->fzp) { if((len=fzp_read(fb->fzp, fb->buf, fb->buf_len))<=0) { // This will happen if file size is a multiple of // input block len. if(fzp_eof(fb->fzp)) { buf->eof_in=1; return RS_DONE; } else { logp("rs_infilebuf_fill: got return %d when trying to read\n", len); return RS_IO_ERROR; } } fb->bytes+=len; if(!MD5_Update(&(fb->md5), fb->buf, len)) { logp("rs_infilebuf_fill: MD5_Update() failed\n"); return RS_IO_ERROR; } } buf->avail_in = len; buf->next_in = fb->buf; return RS_DONE; }