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 void _librsync_deltamaker_dealloc(PyObject* self) { _librsync_DeltaMakerObject *dm = (_librsync_DeltaMakerObject *)self; rs_signature_t *sig_ptr = dm->sig_ptr; rs_free_sumset(sig_ptr); rs_job_free(dm->delta_job); PyObject_Del(self); }
static int make_rev_delta(const char *src, const char *sig, const char *del, int compression, struct conf *cconf) { int ret=-1; FILE *srcfp=NULL; FILE *delfp=NULL; FILE *sigp=NULL; gzFile srczp=NULL; gzFile delzp=NULL; rs_signature_t *sumset=NULL; //logp("make rev delta: %s %s %s\n", src, sig, del); if(!(sigp=open_file(sig, "rb"))) goto end; if(rs_loadsig_file(sigp, &sumset, NULL)!=RS_DONE || rs_build_hash_table(sumset)!=RS_DONE) goto end; //logp("make rev deltb: %s %s %s\n", src, sig, del); if(dpthl_is_compressed(compression, src)) srczp=gzopen_file(src, "rb"); else srcfp=open_file(src, "rb"); if(!srczp && !srcfp) goto end; if(cconf->compression) delzp=gzopen_file(del, comp_level(cconf)); else delfp=open_file(del, "wb"); if(!delzp && !delfp) goto end; if(rs_delta_gzfile(NULL, sumset, srcfp, srczp, delfp, delzp, NULL, cconf->cntr)!=RS_DONE) goto end; ret=0; end: if(sumset) rs_free_sumset(sumset); gzclose_fp(&srczp); close_fp(&srcfp); close_fp(&sigp); if(gzclose_fp(&delzp)) { logp("error closing zp %s in %s\n", del, __func__); ret=-1; } if(close_fp(&delfp)) { logp("error closing fp %s in %s\n", del, __func__); ret=-1; } return ret; }
static void destroy_state(ErlNifEnv *env, void *data) { state_t *state = (state_t *) data; if (state) { if (state->job) rs_job_free(state->job); if (state->out) free(state->out); if (state->in) free(state->in); if (state->sig) rs_free_sumset(state->sig); if (state->bin.data) enif_release_binary(&state->bin); memset(state, 0, sizeof(state_t)); } }
static int load_signature(struct asfd *asfd, rs_signature_t **sumset, struct conf *conf) { rs_result r; rs_job_t *job; job = rs_loadsig_begin(sumset); if((r=do_rs_run(asfd, job, NULL, NULL, NULL, NULL, NULL, asfd->fd, -1, conf->cntr))) { rs_free_sumset(*sumset); return r; } if((r=rs_build_hash_table(*sumset))) return r; rs_job_free(job); return r; }
static int forget_file(struct asfd *asfd, struct sbuf *sb, struct conf *conf) { // Tell the server to forget about this // file, otherwise it might get stuck // on a select waiting for it to arrive. if(asfd->write_str(asfd, CMD_INTERRUPT, sb->path.buf)) return 0; if(sb->path.cmd==CMD_FILE && sb->burp1->datapth.buf) { rs_signature_t *sumset=NULL; // The server will be sending us a signature. // Munch it up then carry on. if(load_signature(asfd, &sumset, conf)) return -1; else rs_free_sumset(sumset); } return 0; }
static rs_result rdiff_delta(poptContext opcon) { FILE *sig_file, *new_file, *delta_file; char const *sig_name; rs_result result; rs_signature_t *sumset; rs_stats_t stats; if (!(sig_name = poptGetArg(opcon))) { rdiff_usage("Usage for delta: " "rdiff [OPTIONS] delta SIGNATURE [NEWFILE [DELTA]]"); return RS_SYNTAX_ERROR; } sig_file = rs_file_open(sig_name, "rb"); new_file = rs_file_open(poptGetArg(opcon), "rb"); delta_file = rs_file_open(poptGetArg(opcon), "wb"); rdiff_no_more_args(opcon); result = rs_loadsig_file(sig_file, &sumset, &stats); if (result != RS_DONE) return result; if (show_stats) rs_log_stats(&stats); if ((result = rs_build_hash_table(sumset)) != RS_DONE) return result; result = rs_delta_file(sumset, new_file, delta_file, &stats); rs_free_sumset(sumset); rs_file_close(delta_file); rs_file_close(new_file); rs_file_close(sig_file); if (show_stats) rs_log_stats(&stats); return result; }
static int forget_file(struct sbuf *sb, char cmd, struct cntr *cntr) { // Tell the server to forget about this // file, otherwise it might get stuck // on a select waiting for it to arrive. if(async_write_str(CMD_INTERRUPT, sb->path)) return 0; if(cmd==CMD_FILE && sb->datapth) { rs_signature_t *sumset=NULL; // The server will be sending // us a signature. Munch it up // then carry on. if(load_signature(&sumset, cntr)) return -1; else rs_free_sumset(sumset); } return 0; }
static int load_signature(rs_signature_t **sumset, struct cntr *cntr) { rs_result r; rs_job_t *job; //logp("loadsig %s\n", rpath); job = rs_loadsig_begin(sumset); if((r=do_rs_run(job, NULL, NULL, NULL, NULL, NULL, async_get_fd(), -1, cntr))) { rs_free_sumset(*sumset); return r; } if((r=rs_build_hash_table(*sumset))) { return r; } rs_job_free(job); //logp("end loadsig\n"); //logp("\n"); return r; }
static int load_signature_and_send_delta(BFILE *bfd, FILE *in, unsigned long long *bytes, unsigned long long *sentbytes, struct cntr *cntr, size_t datalen) { rs_job_t *job; rs_result r; rs_signature_t *sumset=NULL; unsigned char checksum[MD5_DIGEST_LENGTH+1]; rs_filebuf_t *infb=NULL; rs_filebuf_t *outfb=NULL; rs_buffers_t rsbuf; memset(&rsbuf, 0, sizeof(rsbuf)); if(load_signature(&sumset, cntr)) return -1; //logp("start delta\n"); if(!(job=rs_delta_begin(sumset))) { logp("could not start delta job.\n"); rs_free_sumset(sumset); return RS_IO_ERROR; } if(!(infb=rs_filebuf_new(bfd, in, NULL, -1, ASYNC_BUF_LEN, datalen, cntr)) || !(outfb=rs_filebuf_new(NULL, NULL, NULL, async_get_fd(), ASYNC_BUF_LEN, -1, cntr))) { logp("could not rs_filebuf_new for delta\n"); if(infb) rs_filebuf_free(infb); return -1; } //logp("start delta loop\n"); while(1) { size_t wlen=0; rs_result delresult; delresult=rs_async(job, &rsbuf, infb, outfb); if(delresult==RS_DONE) { r=delresult; // logp("delresult done\n"); break; } else if(delresult==RS_BLOCKED || delresult==RS_RUNNING) { // logp("delresult running/blocked: %d\n", delresult); // Keep going } else { logp("error in rs_async for delta: %d\n", delresult); r=delresult; break; } // FIX ME: get it to read stuff (errors, for example) here too. if(async_rw(NULL, NULL, '\0', '\0', NULL, &wlen)) return -1; } if(r!=RS_DONE) logp("delta loop returned: %d\n", r); //logp("after delta loop: %d\n", r); //logp("\n"); if(r==RS_DONE) { *bytes=infb->bytes; *sentbytes=outfb->bytes; if(!MD5_Final(checksum, &(infb->md5))) { logp("MD5_Final() failed\n"); r=RS_IO_ERROR; } } rs_filebuf_free(infb); rs_filebuf_free(outfb); rs_job_free(job); rs_free_sumset(sumset); if(r==RS_DONE && write_endfile(*bytes, checksum)) // finish delta file return -1; //logp("end of load_sig_send_delta\n"); return r; }
static int load_signature_and_send_delta(struct asfd *asfd, BFILE *bfd, FILE *in, unsigned long long *bytes, unsigned long long *sentbytes, struct conf *conf, size_t datalen) { rs_job_t *job; rs_result r; rs_signature_t *sumset=NULL; unsigned char checksum[MD5_DIGEST_LENGTH+1]; rs_filebuf_t *infb=NULL; rs_filebuf_t *outfb=NULL; rs_buffers_t rsbuf; memset(&rsbuf, 0, sizeof(rsbuf)); if(load_signature(asfd, &sumset, conf)) return -1; if(!(job=rs_delta_begin(sumset))) { logp("could not start delta job.\n"); rs_free_sumset(sumset); return RS_IO_ERROR; } if(!(infb=rs_filebuf_new(asfd, bfd, in, NULL, -1, ASYNC_BUF_LEN, datalen, conf->cntr)) || !(outfb=rs_filebuf_new(asfd, NULL, NULL, NULL, asfd->fd, ASYNC_BUF_LEN, -1, conf->cntr))) { logp("could not rs_filebuf_new for delta\n"); if(infb) rs_filebuf_free(infb); return -1; } while(1) { rs_result delresult; delresult=rs_async(job, &rsbuf, infb, outfb); if(delresult==RS_DONE) { r=delresult; break; } else if(delresult==RS_BLOCKED || delresult==RS_RUNNING) { // Keep going } else { logp("error in rs_async for delta: %d\n", delresult); r=delresult; break; } // FIX ME: get it to read stuff (errors, for example) here too. if(asfd->as->rw(asfd->as)) return -1; } if(r!=RS_DONE) logp("delta loop returned: %d\n", r); if(r==RS_DONE) { *bytes=infb->bytes; *sentbytes=outfb->bytes; if(!MD5_Final(checksum, &(infb->md5))) { logp("MD5_Final() failed\n"); r=RS_IO_ERROR; } } rs_filebuf_free(infb); rs_filebuf_free(outfb); rs_job_free(job); rs_free_sumset(sumset); if(r==RS_DONE && write_endfile(asfd, *bytes, checksum)) return -1; return r; }
static int make_rev_delta(const char *src, const char *sig, const char *del, int compression, struct cntr *cntr, struct config *cconf) { gzFile srczp=NULL; FILE *srcfp=NULL; FILE *sigp=NULL; rs_result result; rs_signature_t *sumset=NULL; //logp("make rev delta: %s %s %s\n", src, sig, del); if(!(sigp=open_file(sig, "rb"))) return -1; if((result=rs_loadsig_file(sigp, &sumset, NULL)) || (result=rs_build_hash_table(sumset))) { fclose(sigp); rs_free_sumset(sumset); return result; } fclose(sigp); //logp("make rev deltb: %s %s %s\n", src, sig, del); if(dpth_is_compressed(compression, src)) srczp=gzopen_file(src, "rb"); else srcfp=open_file(src, "rb"); if(!srczp && !srcfp) { rs_free_sumset(sumset); return -1; } if(cconf->compression) { gzFile delzp=NULL; if(!(delzp=gzopen_file(del, comp_level(cconf)))) { gzclose_fp(&srczp); close_fp(&srcfp); rs_free_sumset(sumset); return -1; } result=rs_delta_gzfile(sumset, srcfp, srczp, NULL, delzp, NULL, cntr); gzclose_fp(&delzp); } else { FILE *delfp=NULL; if(!(delfp=open_file(del, "wb"))) { gzclose_fp(&srczp); close_fp(&srcfp); rs_free_sumset(sumset); return -1; } result=rs_delta_gzfile(sumset, srcfp, srczp, delfp, NULL, NULL, cntr); close_fp(&delfp); } rs_free_sumset(sumset); gzclose_fp(&srczp); close_fp(&srcfp); return result; }
int csync_rs_delta(const char *filename) { FILE *sig_file = 0, *new_file = 0, *delta_file = 0; rs_result result; rs_signature_t *sumset; rs_stats_t stats; char tmpfname[MAXPATHLEN]; csync_debug(3, "Csync2 / Librsync: csync_rs_delta('%s')\n", filename); csync_debug(3, "Receiving sig_file from peer..\n"); sig_file = open_temp_file(tmpfname, prefixsubst(filename)); if ( !sig_file ) goto io_error; if (unlink(tmpfname) < 0) goto io_error; if ( csync_recv_file(sig_file) ) { fclose(sig_file); return -1; } result = rs_loadsig_file(sig_file, &sumset, &stats); if (result != RS_DONE) csync_fatal("Got an error from librsync, too bad!\n"); fclose(sig_file); csync_debug(3, "Opening new_file and delta_file..\n"); new_file = fopen(prefixsubst(filename), "rb"); if ( !new_file ) { int backup_errno = errno; csync_debug(0, "I/O Error '%s' while %s in rsync-delta: %s\n", strerror(errno), "opening data file for reading", filename); csync_send_error(); fclose(new_file); errno = backup_errno; return -1; } delta_file = open_temp_file(tmpfname, prefixsubst(filename)); if ( !delta_file ) goto io_error; if (unlink(tmpfname) < 0) goto io_error; csync_debug(3, "Running rs_build_hash_table() from librsync..\n"); result = rs_build_hash_table(sumset); if (result != RS_DONE) csync_fatal("Got an error from librsync, too bad!\n"); csync_debug(3, "Running rs_delta_file() from librsync..\n"); result = rs_delta_file(sumset, new_file, delta_file, &stats); if (result != RS_DONE) csync_fatal("Got an error from librsync, too bad!\n"); csync_debug(3, "Sending delta_file to peer..\n"); csync_send_file(delta_file); csync_debug(3, "Delta has been created successfully.\n"); rs_free_sumset(sumset); fclose(delta_file); fclose(new_file); return 0; io_error: csync_debug(0, "I/O Error '%s' in rsync-delta: %s\n", strerror(errno), prefixsubst(filename)); if (new_file) fclose(new_file); if (delta_file) fclose(delta_file); if (sig_file) fclose(sig_file); return -1; }
/* Given the originfile and newfile, generating a delta and patch to originfile(at the server side anyway) para1: originfile: an original file newfile: new version file basefile: file to be patched with delta on server resfile: newly generated file on server return delta file name */ int compute_delta(char *originfile, char *newfile, char *basefile, char *resfile, char *file_delta_path) { // generate signature rs_stats_t stats; rs_result rsyncresult; rs_signature_t *sumset; char filename[NAME_LEN]; char resname[NAME_LEN]; char file_sig_path[PATH_LEN]; strcpy(file_sig_path, TMP_SIG); //char *file_delta_path = (char *) malloc (PATH_LEN * sizeof(char)); strcpy(file_delta_path, TMP_DELTA); FILE *ofile, *sigfile, *deltafile, *nfile; printf("compute_delta:%s %s %s %s\n", originfile, newfile, basefile, resfile); ofile = fopen(originfile, "rb"); if(ofile == NULL) { printf("origin file %s open error.\n", originfile); return 1; } find_filename(basefile, filename); find_filename(resfile, resname); strcat(file_sig_path, filename); sigfile = fopen(file_sig_path, "wb+"); rsyncresult = rs_sig_file(ofile, sigfile, RS_DEFAULT_BLOCK_LEN, RS_DEFAULT_STRONG_LEN, &stats); if (rsyncresult != RS_DONE) { printf("generate signature Failed!\n"); return 1; } rs_log_stats(&stats); // load sig file fseek(sigfile, 0, 0); rsyncresult = rs_loadsig_file(sigfile, &sumset, &stats, ofile); //rsyncresult = rs_loadsig_file(sigfile, &sumset, &stats); // fix a bug //fclose(ofile); fclose(sigfile); remove(file_sig_path); if (rsyncresult != RS_DONE) { printf("load signature into librsync Failed!\n"); return 1; } rsyncresult = rs_build_hash_table(sumset); if (rsyncresult != RS_DONE) { printf("build hash table in librsync Failed!\n"); rs_free_sumset(sumset); return 1; } rs_log_stats(&stats); // compute delta strcat(file_delta_path, filename); char rand_c[4] = {'\0'}; rand_c[0] = (char)(rand() % 26 + 97); rand_c[1] = (char)(rand() % 26 + 97); rand_c[2] = (char)(rand() % 26 + 97); strcat(file_delta_path, rand_c); deltafile = fopen(file_delta_path, "wb+"); nfile = fopen(newfile,"rb"); if(nfile == NULL) { printf("new file %s open error.\n", newfile); return 1; } rsyncresult = rs_delta_file(sumset, nfile, deltafile, &stats); fclose(ofile); fclose(nfile); fclose(deltafile); if (rsyncresult != RS_DONE) { printf("delta calculation Failed!\n"); rs_free_sumset(sumset); return 1; } rs_log_stats(&stats); rs_free_sumset(sumset); return 0; }
void send_file_delta(const char* new_file_path, const char *sig_file_path, SSL *ssl) { FILE *sig_file; FILE *new_file; FILE *delta_file; size_t result = 0; const size_t max_buffer_size = 1024; char delta_buffer[max_buffer_size]; uint64_t delta_length = 0; rs_result ret; rs_signature_t *sumset; rs_stats_t stats; sig_file = fopen(sig_file_path,"rb"); if(sig_file == NULL) { fprintf(stderr, "failed to open signature file '%s'\n", sig_file_path); exit(1); } new_file = fopen(new_file_path,"rb"); if(new_file == NULL) { fclose(sig_file); fprintf(stderr, "failed to open file '%s'\n", new_file_path); exit(1); } delta_file = tmpfile(); if(delta_file == NULL) { fclose(sig_file); fclose(new_file); fprintf(stderr, "failed to create temporary file\n"); exit(1); } ret = rs_loadsig_file(sig_file, &sumset, &stats); if(ret != RS_DONE) { puts(rs_strerror(ret)); exit(1); } rs_log_stats(&stats); if(rs_build_hash_table(sumset) != RS_DONE) { puts(rs_strerror(ret)); exit(1); } if(rs_delta_file(sumset, new_file, delta_file, &stats) != RS_DONE) { puts(rs_strerror(ret)); exit(1); } fflush(delta_file); do { struct stat buf; if(fstat(fileno(delta_file), &buf) < 0) { perror("fstat"); exit(1); } delta_length = (uint64_t)buf.st_size; }while(0); rewind(delta_file); delta_length = hton64(delta_length); ssl_write_wrapper(ssl, new_file_path, strlen(new_file_path) + 1); ssl_write_wrapper(ssl, &delta_length, 8); while(!feof(delta_file)) { result = fread(delta_buffer, 1, max_buffer_size, delta_file); if(result > 0) ssl_write_wrapper(ssl, delta_buffer, result); } rs_log_stats(&stats); rs_free_sumset(sumset); fclose(sig_file); fclose(new_file); fclose(delta_file); }