static int duplicate_file(const char *oldpath, const char *newpath) { int ret=-1; size_t s=0; size_t t=0; struct fzp *op=NULL; struct fzp *np=NULL; char buf[DUP_CHUNK]=""; if(!(op=fzp_open(oldpath, "rb")) || !(np=fzp_open(newpath, "wb"))) goto end; while((s=fzp_read(op, buf, DUP_CHUNK))>0) { t=fzp_write(np, buf, s); if(t!=s) { logp("could not write all bytes: %lu!=%lu\n", (unsigned long)s, (unsigned long)t); goto end; } } ret=0; end: fzp_close(&np); fzp_close(&op); if(ret) logp("could not duplicate %s to %s\n", oldpath, newpath); return ret; }
static int make_rev_sig(const char *dst, const char *sig, const char *endfile, int compression, struct conf **confs) { int ret=-1; struct fzp *dstfzp=NULL; struct fzp *sigp=NULL; //logp("make rev sig: %s %s\n", dst, sig); if(dpth_protocol1_is_compressed(compression, dst)) dstfzp=fzp_gzopen(dst, "rb"); else dstfzp=fzp_open(dst, "rb"); if(!dstfzp || !(sigp=fzp_open(sig, "wb")) || rs_sig_gzfile(dstfzp, sigp, get_librsync_block_len(endfile), RS_DEFAULT_STRONG_LEN, confs)!=RS_DONE) goto end; ret=0; end: //logp("end of make rev sig\n"); fzp_close(&dstfzp); if(fzp_close(&sigp)) { logp("error closing %s in %s\n", sig, __func__); return -1; } return ret; }
struct slist *build_manifest_with_data_files(const char *path, const char *datapath, int entries, int data_files) { struct blk *b=NULL; struct slist *slist=NULL; struct manio *manio=NULL; struct fzp *fzp=NULL; char spath[256]=""; char cpath[256]=""; fail_unless((manio=manio_open_phase3(path, "wb", PROTO_2, RMANIFEST_RELATIVE))!=NULL); slist=do_build_manifest(manio, PROTO_2, entries, data_files); fail_unless(!manio_close(&manio)); for(b=slist->blist->head; b; b=b->next) { snprintf(spath, sizeof(spath), "%s/%s", datapath, uint64_to_savepathstr(b->savepath)); if(strcmp(spath, cpath)) { snprintf(cpath, sizeof(cpath), "%s", spath); fzp_close(&fzp); } if(!fzp) { fail_unless(!build_path_w(cpath)); fail_unless((fzp=fzp_open(cpath, "wb"))!=NULL); } fzp_printf(fzp, "%c%04X%s", CMD_DATA, strlen("data"), "data"); } fzp_close(&fzp); return slist; }
// Also used by restore.c. // FIX THIS: This stuff is very similar to make_rev_delta, can maybe share // some code. int do_patch(struct asfd *asfd, const char *dst, const char *del, const char *upd, bool gzupd, int compression) { struct fzp *dstp=NULL; struct fzp *delfzp=NULL; struct fzp *upfzp=NULL; rs_result result=RS_IO_ERROR; if(!(dstp=fzp_open(dst, "rb"))) goto end; if(!(delfzp=fzp_gzopen(del, "rb"))) goto end; if(gzupd) upfzp=fzp_gzopen(upd, comp_level(compression)); else upfzp=fzp_open(upd, "wb"); if(!upfzp) goto end; result=rs_patch_gzfile(dstp, delfzp, upfzp); end: fzp_close(&dstp); fzp_close(&delfzp); if(fzp_close(&upfzp)) { logp("error closing %s in %s\n", upd, __func__); result=RS_IO_ERROR; } return result; }
static int make_rev_delta(const char *src, const char *sig, const char *del, int compression, struct conf **cconfs) { int ret=-1; rs_result result; struct fzp *srcfzp=NULL; struct fzp *delfzp=NULL; struct fzp *sigp=NULL; rs_signature_t *sumset=NULL; //logp("make rev delta: %s %s %s\n", src, sig, del); if(!(sigp=fzp_open(sig, "rb"))) goto end; if((result=rs_loadsig_fzp(sigp, &sumset))!=RS_DONE) { logp("rs_loadsig_fzp returned %d %s\n", result, rs_strerror(result)); goto end; } if((result=rs_build_hash_table(sumset))!=RS_DONE) { logp("rs_build_hash_table returned %d %s\n", result, rs_strerror(result)); goto end; } //logp("make rev deltb: %s %s %s\n", src, sig, del); if(dpth_protocol1_is_compressed(compression, src)) srcfzp=fzp_gzopen(src, "rb"); else srcfzp=fzp_open(src, "rb"); if(!srcfzp) goto end; if(get_int(cconfs[OPT_COMPRESSION])) delfzp=fzp_gzopen(del, comp_level(get_int(cconfs[OPT_COMPRESSION]))); else delfzp=fzp_open(del, "wb"); if(!delfzp) goto end; if((result=rs_delta_gzfile(sumset, srcfzp, delfzp))!=RS_DONE) { logp("rs_delta_gzfile returned %d %s\n", result, rs_strerror(result)); goto end; } ret=0; end: if(sumset) rs_free_sumset(sumset); fzp_close(&srcfzp); fzp_close(&sigp); if(fzp_close(&delfzp)) { logp("error closing delfzp %s in %s\n", del, __func__); ret=-1; } return ret; }
static int bcompress(const char *src, const char *dst, int compression) { int res; int got; struct fzp *sfzp=NULL; struct fzp *dfzp=NULL; char buf[ZCHUNK]; if(!(sfzp=fzp_open(src, "rb")) || !(dfzp=fzp_gzopen(dst, comp_level(compression)))) goto error; while((got=fzp_read(sfzp, buf, sizeof(buf)))>0) { res=fzp_write(dfzp, buf, got); if(res!=got) { logp("compressing %s - read %d but wrote %d\n", src, got, res); goto error; } } fzp_close(&sfzp); return fzp_close(&dfzp); error: fzp_close(&sfzp); fzp_close(&dfzp); return -1; }
int manio_close(struct manio *manio) { if(manio_closed(manio)) return 0; if(sort_and_write_hooks(manio) || sort_and_write_dindex(manio)) { fzp_close(&(manio->fzp)); return -1; } return fzp_close(&(manio->fzp)); }
void sbuf_protocol1_free_content(struct protocol1 *protocol1) { if(!protocol1) return; memset(&(protocol1->rsbuf), 0, sizeof(protocol1->rsbuf)); if(protocol1->sigjob) { rs_job_free(protocol1->sigjob); protocol1->sigjob=NULL; } rs_filebuf_free(&protocol1->infb); rs_filebuf_free(&protocol1->outfb); fzp_close(&protocol1->sigfzp); fzp_close(&protocol1->fzp); sbuf_protocol1_init(protocol1); }
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; }
static void check_dindex(int i) { int ret; struct fzp *fzp; const char *p; struct iobuf rbuf; int lines=0; struct blk blk; uint64_t last_savepath=0; p=get_extra_path(i, "dindex"); memset(&rbuf, 0, sizeof(rbuf)); fail_unless((fzp=fzp_gzopen(p, "rb"))!=NULL); while(!(ret=iobuf_fill_from_fzp(&rbuf, fzp))) { lines++; switch(rbuf.cmd) { case CMD_SAVE_PATH: blk_set_from_iobuf_savepath(&blk, &rbuf); fail_unless(blk.savepath>last_savepath); last_savepath=blk.savepath; break; default: fail_unless(0==1); break; } iobuf_free_content(&rbuf); } fail_unless(ret==1); fail_unless(lines>500); fail_unless(!fzp_close(&fzp)); }
int log_fzp_set(const char *path, struct conf **confs) { fzp_close(&logfzp); if(path) { logp("Logging to %s\n", path); if(!(logfzp=fzp_open(path, "ab"))) return -1; } if(logfzp) fzp_setlinebuf(logfzp); do_syslog=get_int(confs[OPT_SYSLOG]); if(force_quiet) { do_stdout=0; do_progress_counter=0; } else { do_stdout=get_int(confs[OPT_STDOUT]); do_progress_counter=get_int(confs[OPT_PROGRESS_COUNTER]); } if(syslog_opened) { closelog(); syslog_opened=0; } if(do_syslog) { openlog(prog, LOG_PID, LOG_USER); syslog_opened++; } return 0; }
static struct fzp *fzp_do_open(const char *path, const char *mode, enum fzp_type type) { struct fzp *fzp=NULL; if(!(fzp=fzp_alloc())) goto error; fzp->type=type; switch(type) { case FZP_FILE: if(!(fzp->fp=open_fp(path, mode))) goto error; return fzp; case FZP_COMPRESSED: if(!(fzp->zp=open_zp(path, mode))) goto error; return fzp; default: unknown_type(fzp->type, __func__); goto error; } error: fzp_close(&fzp); return NULL; }
int run_bsigs(int argc, char *argv[]) { int ret=1; fzp *fzp=NULL; struct iobuf rbuf; struct blk blk; memset(&rbuf, 0, sizeof(struct iobuf)); if(argc!=2) return usage(); path=argv[1]; if(!(fzp=fzp_gzopen(path, "rb"))) goto end; while(1) { iobuf_free_content(&rbuf); switch(iobuf_fill_from_fzp(&rbuf, fzp)) { case 1: ret=0; // Finished OK. case -1: goto end; // Error. } if(parse_cmd(&rbuf, &blk)) goto end; } end: iobuf_free_content(&rbuf); fzp_close(&fzp); return ret; }
static void tear_down(struct asfd **asfd) { asfd_free(asfd); fail_unless(!fzp_close(&output)); fail_unless(!recursive_delete(CLIENTCONFDIR)); alloc_check(); }
int manio_read_fcount(struct manio *manio) { int ret=-1; size_t s; struct fzp *fzp=NULL; char *path=NULL; char buf[16]=""; if(!(path=get_fcount_path(manio)) || !(fzp=fzp_open(path, "rb"))) goto end; if(!fzp_gets(fzp, buf, sizeof(buf))) { logp("fzp_gets on %s failed\n", path); goto end; } s=strlen(buf); if(s!=9) { logp("data in %s is not the right length (%s!=9)\n", s); goto end; } manio->offset->fcount=strtoul(buf, NULL, 16); ret=0; end: fzp_close(&fzp); free_w(&path); return ret; }
int manio_close(struct manio **manio) { int ret=0; // int fd; if(!manio || !*manio) return ret; if(sort_and_write_hooks_and_dindex(*manio)) ret=-1; /* There is no gzfileno() if((fd=fzp_fileno((*manio)->fzp))<0) { logp("Could not get fileno in %s for %s: %s\n", __func__, (*manio)->manifest, strerror(errno)); ret=-1; } if(fsync(fd)) { logp("Error in fsync in %s for %s: %s\n", __func__, (*manio)->manifest, strerror(errno)); ret=-1; } */ if(fzp_close(&((*manio)->fzp))) ret=-1; sync(); manio_free_content(*manio); free_v((void **)manio); return ret; }
// Return -1 for error, 0 for stuff read OK, 1 for end of files. int manio_read_with_blk(struct manio *manio, struct sbuf *sb, struct blk *blk, struct sdirs *sdirs) { while(1) { if(!manio->fzp) { if(manio_open_next_fpath(manio)) goto error; if(!manio->fzp) return 1; // No more files to read. } switch(sbuf_fill_from_file(sb, manio->fzp, blk, sdirs?sdirs->data:NULL)) { case 0: return 0; // Got something. case 1: break; // Keep going. default: goto error; // Error. } // Reached the end of the current file. // Maybe there is another file to continue with. if(sort_and_write_hooks_and_dindex(manio) || fzp_close(&manio->fzp)) goto error; if(is_single_file(manio)) return 1; } error: return -1; }
static int incexc_matches(const char *fullrealwork, const char *incexc) { int ret=0; int got=0; struct fzp *fzp=NULL; char buf[4096]=""; const char *inc=NULL; char *old_incexc_path=NULL; if(!(old_incexc_path=prepend_s(fullrealwork, "incexc"))) return -1; if(!(fzp=fzp_open(old_incexc_path, "rb"))) { // Assume that no incexc file could be found because the client // was on an old version. Assume resume is OK and return 1. ret=1; goto end; } inc=incexc; while((got=fzp_read(fzp, buf, sizeof(buf)))>0) { if(strlen(inc)<(size_t)got) break; if(strncmp(buf, inc, got)) break; inc+=got; } if(inc && strlen(inc)) ret=0; else ret=1; end: fzp_close(&fzp); free_w(&old_incexc_path); return ret; }
static int flag_wrap_str_zp(struct bu *bu, uint16_t flag, const char *field, const char *logfile) { int ret=-1; struct fzp *fzp=NULL; if(!flag_matches(bu, flag) || !logfile || strcmp(logfile, field)) return 0; if(!(fzp=open_backup_log(bu, logfile))) goto end; if(yajl_gen_str_w(field)) goto end; if(yajl_array_open_w()) goto end; if(fzp) { char *cp=NULL; char buf[1024]=""; while(fzp_gets(fzp, buf, sizeof(buf))) { if((cp=strrchr(buf, '\n'))) *cp='\0'; if(yajl_gen_str_w(buf)) goto end; } } if(yajl_array_close_w()) goto end; ret=0; end: fzp_close(&fzp); return ret; }
int status_client_ncurses(struct conf **confs) { int ret=-1; int csin=-1; int csout=-1; pid_t childpid=-1; struct async *as=NULL; const char *monitor_logfile=get_string(confs[OPT_MONITOR_LOGFILE]); struct asfd *so_asfd=NULL; struct sel *sel=NULL; if(!(sel=sel_alloc())) goto end; setup_signals(); // Fork a burp child process that will contact the server over SSL. // We will read and write from and to its stdout and stdin. if((childpid=fork_monitor(&csin, &csout, confs))<0) goto end; //printf("childpid: %d\n", childpid); if(!(as=async_alloc()) || as->init(as, 0) || !setup_asfd_linebuf_write(as, "monitor stdin", &csin) || !setup_asfd_linebuf_read(as, "monitor stdout", &csout)) goto end; //printf("ml: %s\n", monitor_logfile); #ifdef HAVE_NCURSES if(actg==ACTION_STATUS) { if(!setup_asfd_ncurses_stdin(as)) goto end; ncurses_init(); } #endif if(!(so_asfd=setup_asfd_stdout(as))) goto end; if(monitor_logfile && !(lfzp=fzp_open(monitor_logfile, "wb"))) goto end; log_fzp_set_direct(lfzp); ret=status_client_ncurses_main_loop(as, so_asfd, sel, get_string(confs[OPT_ORIG_CLIENT])); end: #ifdef HAVE_NCURSES if(actg==ACTION_STATUS) ncurses_free(); #endif if(ret) logp("%s exiting with error: %d\n", __func__, ret); fzp_close(&lfzp); async_asfd_free_all(&as); close_fd(&csin); close_fd(&csout); sel_free(&sel); return ret; }
int manio_seek(struct manio *manio, man_off_t *offset) { fzp_close(&manio->fzp); man_off_t_memcpy(&manio->offset, offset); if(!(manio->fzp=fzp_gzopen(manio->offset.fpath, manio->mode))) return -1; return fzp_seek(manio->fzp, manio->offset.offset, SEEK_SET); }
static int reset_sig_count_and_close(struct manio *manio) { if(sort_and_write_hooks_and_dindex(manio)) return -1; if(fzp_close(&manio->fzp)) return -1; manio->sig_count=0; if(manio_open_next_fpath(manio)) return -1; return 0; }
static void rblk_free_content(struct rblk *rblk) { for(int j=0; j<rblk->rlen; j++) { rblk_mem-=rblk->readbuf[j].len; iobuf_free_content(&rblk->readbuf[j]); } fzp_close(&rblk->fzp); }
static int create_zero_length_file(const char *path) { int ret=0; struct fzp *dest; if(!(dest=fzp_open(path, "wb"))) ret=-1; ret|=fzp_close(&dest); return ret; }
static int sort_and_write_dindex(struct manio *manio) { int i; int ret=-1; struct fzp *fzp=NULL; char msg[32]=""; char *path=NULL; struct iobuf wbuf; struct blk blk; int dindex_count=manio->dindex_count; uint64_t *dindex_sort=manio->dindex_sort; if(!dindex_sort) return 0; snprintf(msg, sizeof(msg), "%08"PRIX64, manio->offset->fcount-1); if(!(path=prepend_s(manio->dindex_dir, msg)) || build_path_w(path) || !(fzp=fzp_gzopen(path, MANIO_MODE_WRITE))) goto end; qsort(dindex_sort, dindex_count, sizeof(uint64_t), uint64_t_sort); for(i=0; i<dindex_count; i++) { // Do not bother with duplicates. if(i && dindex_sort[i]==dindex_sort[i-1]) continue; blk.savepath=dindex_sort[i]; blk_to_iobuf_savepath(&blk, &wbuf); if(iobuf_send_msg_fzp(&wbuf, fzp)) return -1; } if(fzp_close(&fzp)) { logp("Error closing %s in %s: %s\n", path, __func__, strerror(errno)); goto end; } manio->dindex_count=0; ret=0; end: fzp_close(&fzp); free_w(&path); return ret; }
static int sort_and_write_hooks(struct manio *manio) { int i; int ret=-1; struct fzp *fzp=NULL; char msg[32]=""; char *path=NULL; int hook_count=manio->hook_count; uint64_t *hook_sort=manio->hook_sort; if(!hook_sort) return 0; snprintf(msg, sizeof(msg), "%08"PRIX64, manio->offset->fcount-1); if(!(path=prepend_s(manio->hook_dir, msg)) || build_path_w(path) || !(fzp=fzp_gzopen(path, MANIO_MODE_WRITE))) goto end; qsort(hook_sort, hook_count, sizeof(uint64_t), uint64_t_sort); if(write_hook_header(fzp, manio->rmanifest, msg)) goto end; for(i=0; i<hook_count; i++) { // Do not bother with duplicates. if(i && hook_sort[i]==hook_sort[i-1]) continue; if(to_fzp_fingerprint(fzp, hook_sort[i])) goto end; } if(fzp_close(&fzp)) { logp("Error closing %s in %s: %s\n", path, __func__, strerror(errno)); goto end; } if(manio_write_fcount(manio)) goto end; manio->hook_count=0; ret=0; end: fzp_close(&fzp); free_w(&path); return ret; }
static int sort_and_write_hooks(struct manio *manio) { int i; int ret=-1; struct fzp *fzp=NULL; char comp[32]=""; char *path=NULL; int hook_count=manio->hook_count; char **hook_sort=manio->hook_sort; if(!hook_sort) return 0; snprintf(comp, sizeof(comp), "%08"PRIX64, manio->offset.fcount-1); if(!(path=prepend_s(manio->hook_dir, comp)) || build_path_w(path) || !(fzp=fzp_gzopen(path, manio->mode))) goto end; qsort(hook_sort, hook_count, sizeof(char *), strsort); if(write_hook_header(manio, fzp, comp)) goto end; for(i=0; i<hook_count; i++) { // Do not bother with duplicates. if(i && !strcmp(hook_sort[i], hook_sort[i-1])) continue; fzp_printf(fzp, "%c%04X%s\n", CMD_FINGERPRINT, (unsigned int)strlen(hook_sort[i]), hook_sort[i]); } if(fzp_close(&fzp)) { logp("Error closing %s in %s: %s\n", path, __func__, strerror(errno)); goto end; } if(manio_write_fcount(manio)) goto end; manio->hook_count=0; ret=0; end: fzp_close(&fzp); free_w(&path); return ret; }
static void assert_file_content(const char *path, const char *content) { size_t got; struct fzp *fp; size_t len=strlen(content); char buf[256]=""; fail_unless((fp=fzp_gzopen(path, "rb"))!=NULL); got=fzp_read(fp, buf, len); fail_unless(len==got); fail_unless(!strcmp(buf, content)); fzp_close(&fp); }
int manio_seek(struct manio *manio, man_off_t *offset) { fzp_close(&manio->fzp); if(!(manio->fzp=fzp_gzopen(offset->fpath, manio->mode)) || fzp_seek(manio->fzp, offset->offset, SEEK_SET)) return -1; man_off_t_free_content(manio->offset); if(!(manio->offset->fpath=strdup_w(offset->fpath, __func__))) return -1; manio->offset->offset=offset->offset; manio->offset->fcount=offset->fcount; return 0; }
END_TEST START_TEST(test_protocol1_verify_file_gzip_read_failure) { struct asfd *asfd; struct cntr *cntr; struct sbuf *sb; const char *path="somepath"; const char *datapth="/datapth"; const char *endfile="0:0"; const char *best=BASE "/existent"; const char *plain_text="some plain text"; size_t s; struct fzp *fzp; s=strlen(plain_text); clean(); cntr=setup_cntr(); sb=setup_sbuf(path, datapth, endfile, 1/*compression*/); // Make a corrupt gzipped file. build_path_w(best); fail_unless((fzp=fzp_gzopen(best, "wb"))!=NULL); fail_unless(fzp_write(fzp, plain_text, s)==s); fail_unless(!fzp_close(&fzp)); fail_unless((fzp=fzp_open(best, "r+b"))!=NULL); fail_unless(!fzp_seek(fzp, 10, SEEK_SET)); fail_unless(fzp_write(fzp, "aa", 2)==2); fail_unless(!fzp_close(&fzp)); asfd=asfd_mock_setup(&areads, &awrites); setup_error_while_reading(asfd, best); // Returns 0 so that the parent process continues. fail_unless(!verify_file(asfd, sb, 0 /*patches*/, best, cntr)); fail_unless(cntr->ent[CMD_WARNING]->count==1); tear_down(&sb, &cntr, NULL, &asfd); }