static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs, struct sbuf *rb, FILE *p2fp, struct conf *cconf, char **last_requested) { static char *cp=NULL; static struct iobuf *rbuf; rbuf=asfd->rbuf; // Finished the file. // Write it to the phase2 file, and free the buffers. if(close_fp(&(rb->burp1->fp))) { logp("error closing delta for %s in receive\n", rb->path); goto error; } if(gzclose_fp(&(rb->burp1->zp))) { logp("error gzclosing delta for %s in receive\n", rb->path); goto error; } iobuf_copy(&rb->burp1->endfile, rbuf); rbuf->buf=NULL; if(rb->flags & SBUFL_RECV_DELTA && finish_delta(sdirs, rb)) goto error; if(sbufl_to_manifest(rb, p2fp, NULL)) goto error; if(rb->flags & SBUFL_RECV_DELTA) cntr_add_changed(cconf->cntr, rb->path.cmd); else cntr_add(cconf->cntr, rb->path.cmd, 0); if(*last_requested && !strcmp(rb->path.buf, *last_requested)) { free(*last_requested); *last_requested=NULL; } cp=strchr(rb->burp1->endfile.buf, ':'); if(rb->burp1->endfile.buf) cntr_add_bytes(cconf->cntr, strtoull(rb->burp1->endfile.buf, NULL, 10)); if(cp) { // checksum stuff goes here } sbuf_free_content(rb); return 0; error: sbuf_free_content(rb); return -1; }
static int process_unchanged_file(struct sbuf *cb, FILE *ucfp, struct conf *cconf) { if(sbufl_to_manifest(cb, ucfp, NULL)) { sbuf_free_content(cb); return -1; } else { cntr_add_same(cconf->cntr, cb->path.cmd); } if(cb->burp1->endfile.buf) cntr_add_bytes(cconf->cntr, strtoull(cb->burp1->endfile.buf, NULL, 10)); sbuf_free_content(cb); return 1; }
static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs, struct sbuf *rb, struct manio *chmanio, struct conf **cconfs, char **last_requested) { int ret=-1; static char *cp=NULL; static struct iobuf *rbuf; struct cntr *cntr=get_cntr(cconfs); rbuf=asfd->rbuf; // Finished the file. // Write it to the phase2 file, and free the buffers. if(fzp_close(&(rb->protocol1->fzp))) { logp("error closing delta for %s in receive\n", rb->path.buf); goto end; } iobuf_move(&rb->endfile, rbuf); if(rb->flags & SBUF_RECV_DELTA && finish_delta(sdirs, rb)) goto end; if(manio_write_sbuf(chmanio, rb)) goto end; if(rb->flags & SBUF_RECV_DELTA) cntr_add_changed(cntr, rb->path.cmd); else cntr_add(cntr, rb->path.cmd, 0); if(*last_requested && !strcmp(rb->path.buf, *last_requested)) free_w(last_requested); cp=strchr(rb->endfile.buf, ':'); if(rb->endfile.buf) cntr_add_bytes(cntr, strtoull(rb->endfile.buf, NULL, 10)); if(cp) { // checksum stuff goes here } ret=0; end: sbuf_free_content(rb); return ret; }
static int process_unchanged_file(struct sbuf *p1b, struct sbuf *cb, struct fzp *ucfp, struct conf **cconfs) { // Need to re-encode the p1b attribs to include compression and // other bits and pieces that are recorded on cb. iobuf_move(&p1b->protocol1->datapth, &cb->protocol1->datapth); iobuf_move(&p1b->protocol1->endfile, &cb->protocol1->endfile); p1b->compression=cb->compression; if(attribs_encode(p1b)) return -1; if(sbufl_to_manifest(p1b, ucfp)) return -1; cntr_add_same(get_cntr(cconfs[OPT_CNTR]), p1b->path.cmd); if(p1b->protocol1->endfile.buf) cntr_add_bytes( get_cntr(cconfs[OPT_CNTR]), strtoull(p1b->protocol1->endfile.buf, NULL, 10)); sbuf_free_content(cb); return 1; }
static int process_data_dir_file(struct asfd *asfd, struct bu *bu, struct bu *b, const char *path, struct sbuf *sb, enum action act, struct sdirs *sdirs, struct conf **cconfs) { int ret=-1; int patches=0; char *dpath=NULL; struct stat dstatp; const char *tmp=NULL; const char *best=NULL; uint64_t bytes=0; static char *tmppath1=NULL; static char *tmppath2=NULL; struct cntr *cntr=NULL; if(cconfs) cntr=get_cntr(cconfs); if((!tmppath1 && !(tmppath1=prepend_s(sdirs->client, "tmp1"))) || (!tmppath2 && !(tmppath2=prepend_s(sdirs->client, "tmp2")))) goto end; best=path; tmp=tmppath1; // Now go down the list, applying any deltas. for(b=b->prev; b && b->next!=bu; b=b->prev) { free_w(&dpath); if(!(dpath=prepend_s(b->delta, sb->protocol1->datapth.buf))) goto end; if(lstat(dpath, &dstatp) || !S_ISREG(dstatp.st_mode)) continue; if(!patches) { // Need to gunzip the first one. if(inflate_or_link_oldfile(asfd, best, tmp, cconfs, sb->compression)) { char msg[256]=""; snprintf(msg, sizeof(msg), "error when inflating %s\n", best); log_and_send(asfd, msg); goto end; } best=tmp; if(tmp==tmppath1) tmp=tmppath2; else tmp=tmppath1; } if(do_patch(asfd, best, dpath, tmp, 0 /* do not gzip the result */, sb->compression /* from the manifest */, cconfs)) { char msg[256]=""; snprintf(msg, sizeof(msg), "error when patching %s\n", path); log_and_send(asfd, msg); goto end; } best=tmp; if(tmp==tmppath1) tmp=tmppath2; else tmp=tmppath1; unlink(tmp); patches++; } switch(act) { case ACTION_RESTORE: if(send_file(asfd, sb, patches, best, &bytes, cntr)) goto end; break; case ACTION_VERIFY: if(verify_file(asfd, sb, patches, best, &bytes, cntr)) goto end; break; default: logp("Unknown action: %d\n", act); goto end; } cntr_add(cntr, sb->path.cmd, 0); cntr_add_bytes(cntr, strtoull(sb->endfile.buf, NULL, 10)); cntr_add_sentbytes(cntr, bytes); ret=0; end: free_w(&dpath); return ret; }
static #endif int get_last_good_entry(struct manio *manio, struct iobuf *result, struct cntr *cntr, struct dpth *dpth, enum protocol protocol, man_off_t **pos) { int ars=0; int got_vss_start=0; struct sbuf *sb=NULL; struct iobuf lastpath; if(!(sb=sbuf_alloc(protocol))) goto error; iobuf_init(&lastpath); man_off_t_free(pos); if(!(*pos=manio_tell(manio))) { logp("Could not manio_tell first pos in %s(): %s\n", __func__, strerror(errno)); goto error; } while(1) { if(sb->path.buf && !got_vss_start) { iobuf_free_content(&lastpath); iobuf_move(&lastpath, &sb->path); if(!sbuf_is_filedata(sb) && !sbuf_is_vssdata(sb)) { iobuf_free_content(result); iobuf_move(result, &lastpath); man_off_t_free(pos); if(!(*pos=manio_tell(manio))) { logp("Could not manio_tell pos in %s(): %s\n", __func__, strerror(errno)); goto error; } } } if(sb->endfile.buf && !got_vss_start) { iobuf_free_content(result); iobuf_move(result, &lastpath); man_off_t_free(pos); if(!(*pos=manio_tell(manio))) { logp("Could not manio_tell pos in %s(): %s\n", __func__, strerror(errno)); goto error; } } sbuf_free_content(sb); ars=manio_read(manio, sb); if(dpth && set_higher_datapth(sb, dpth)) goto error; switch(ars) { case 0: break; case 1: iobuf_free_content(&lastpath); sbuf_free(&sb); return 0; default: if(result->buf) logp("Error after %s in %s()\n", result->buf, __func__); // Treat error in changed manio as // OK - could have been a short write. iobuf_free_content(&lastpath); sbuf_free(&sb); return 0; } // Some hacks for split_vss. switch(sb->path.cmd) { case CMD_VSS: case CMD_ENC_VSS: got_vss_start=1; break; case CMD_VSS_T: case CMD_ENC_VSS_T: got_vss_start=0; break; case CMD_FILE: case CMD_ENC_FILE: if(S_ISDIR(sb->statp.st_mode)) got_vss_start=0; break; default: break; } if(cntr) { // FIX THIS: cannot distinguish between new and // changed files. cntr_add_changed(cntr, sb->path.cmd); if(sb->endfile.buf) { uint64_t e=strtoull(sb->endfile.buf, NULL, 10); cntr_add_bytes(cntr, e); } } } error: iobuf_free_content(&lastpath); sbuf_free(&sb); man_off_t_free(pos); return -1; }
static #endif int forward_before_entry(struct manio *manio, struct iobuf *target, struct cntr *cntr, struct dpth *dpth, enum protocol protocol, man_off_t **pos) { int ars=0; struct sbuf *sb=NULL; if(!(sb=sbuf_alloc(protocol))) goto error; man_off_t_free(pos); if(!(*pos=manio_tell(manio))) { logp("Could not manio_tell first pos in %s(): %s\n", __func__, strerror(errno)); goto error; } while(1) { if(sb->endfile.buf || (sb->path.buf && !sbuf_is_filedata(sb))) { man_off_t_free(pos); if(!(*pos=manio_tell(manio))) { logp("Could not manio_tell pos in %s(): " "%s\n", __func__, strerror(errno)); goto error; } } sbuf_free_content(sb); ars=manio_read(manio, sb); if(dpth && set_higher_datapth(sb, dpth)) goto error; switch(ars) { case 0: break; case 1: sbuf_free(&sb); return 0; default: logp("Error in %s(), but continuing\n", __func__); // Treat error in unchanged manio as // OK - could have been a short write. sbuf_free(&sb); return 0; } if(iobuf_pathcmp(target, &sb->path)<=0) { sbuf_free(&sb); return 0; } if(cntr) { cntr_add_same(cntr, sb->path.cmd); if(sb->endfile.buf) { uint64_t e=strtoull(sb->endfile.buf, NULL, 10); cntr_add_bytes(cntr, e); } } } error: sbuf_free(&sb); man_off_t_free(pos); return -1; }
static int deal_with_data(struct asfd *asfd, struct sbuf *sb, BFILE *bfd, size_t *datalen, struct conf *conf) { int ret=-1; int forget=0; FILE *fp=NULL; size_t elen=0; char *extrameta=NULL; unsigned long long bytes=0; sb->compression=conf->compression; iobuf_copy(&sb->path, asfd->rbuf); iobuf_init(asfd->rbuf); #ifdef HAVE_WIN32 if(win32_lstat(sb->path.buf, &sb->statp, &sb->winattr)) #else if(lstat(sb->path.buf, &sb->statp)) #endif { logw(asfd, conf, "Path has vanished: %s", sb->path.buf); if(forget_file(asfd, sb, conf)) goto error; goto end; } if(size_checks(asfd, sb, conf)) forget++; if(!forget) { sb->compression=in_exclude_comp(conf->excom, sb->path.buf, conf->compression); if(attribs_encode(sb)) goto error; else if(open_file_for_sendl(asfd, #ifdef HAVE_WIN32 bfd, NULL, #else NULL, &fp, #endif sb->path.buf, sb->winattr, datalen, conf->atime, conf)) forget++; } if(forget) { if(forget_file(asfd, sb, conf)) goto error; goto end; } if(sb->path.cmd==CMD_METADATA || sb->path.cmd==CMD_ENC_METADATA || sb->path.cmd==CMD_VSS || sb->path.cmd==CMD_ENC_VSS #ifdef HAVE_WIN32 || conf->strip_vss #endif ) { if(get_extrameta(asfd, #ifdef HAVE_WIN32 bfd, #endif sb->path.buf, &sb->statp, &extrameta, &elen, sb->winattr, conf, datalen)) { logw(asfd, conf, "Meta data error for %s", sb->path.buf); goto end; } if(extrameta) { #ifdef HAVE_WIN32 if(conf->strip_vss) { free(extrameta); extrameta=NULL; elen=0; } #endif } else { logw(asfd, conf, "No meta data after all: %s", sb->path.buf); goto end; } } if(sb->path.cmd==CMD_FILE && sb->burp1->datapth.buf) { unsigned long long sentbytes=0; // Need to do sig/delta stuff. if(asfd->write(asfd, &(sb->burp1->datapth)) || asfd->write(asfd, &sb->attr) || asfd->write(asfd, &sb->path) || load_signature_and_send_delta(asfd, bfd, fp, &bytes, &sentbytes, conf, *datalen)) { logp("error in sig/delta for %s (%s)\n", sb->path.buf, sb->burp1->datapth.buf); goto end; } else { cntr_add(conf->cntr, CMD_FILE_CHANGED, 1); cntr_add_bytes(conf->cntr, bytes); cntr_add_sentbytes(conf->cntr, sentbytes); } } else { //logp("need to send whole file: %s\n", sb.path); // send the whole file. if((asfd->write(asfd, &sb->attr) || asfd->write(asfd, &sb->path)) || send_whole_file_w(asfd, sb, NULL, 0, &bytes, conf->encryption_password, conf, sb->compression, bfd, fp, extrameta, elen, *datalen)) goto end; else { cntr_add(conf->cntr, sb->path.cmd, 1); cntr_add_bytes(conf->cntr, bytes); cntr_add_sentbytes(conf->cntr, bytes); } } end: ret=0; error: #ifdef HAVE_WIN32 // If using Windows do not close bfd - it needs // to stay open to read VSS/file data/VSS. // It will get closed either when given a // different file path, or when this function // exits. #else close_file_for_sendl(NULL, &fp, asfd); #endif sbuf_free_content(sb); if(extrameta) free(extrameta); return ret; }