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; }
bool rsync_delta(char* newfile,char* sigfile,char* deltafile){ FILE* sig=FileUtil::rs_file_open(sigfile,"rb"); rs_signature_t* sumset; rs_result rs=rs_loadsig_file(sig,&sumset,NULL); if(rs!=RS_DONE){ FileUtil::rs_file_close(sig); return false;} rs=rs_build_hash_table(sumset); if(rs!=RS_DONE){ FileUtil::rs_file_close(sig); return false;} FILE* newf=FileUtil::rs_file_open(newfile,"rb"); FILE* delta=FileUtil::rs_file_open(deltafile,"wb"); rs=rs_delta_file(sumset,newf,delta,NULL); FileUtil::rs_file_close(sig); FileUtil::rs_file_close(newf); FileUtil::rs_file_close(delta); if(rs!=RS_DONE){ return false;} return true; }
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); }