/* 生成指定项目的指定文件的 rsync 签名文件 */ FILE *rsync_sig(const std::string &project_name, const std::string &path) { std::string tmp; FILE *basis_file; FILE *sig_file; size_t block_len = RS_DEFAULT_BLOCK_LEN; size_t strong_len = RS_DEFAULT_STRONG_LEN; rs_result ret; rs_stats_t stats; tmp = project_name + "/current/" + path; basis_file = fopen(tmp.c_str(), "rb"); //打开旧文件 if(basis_file == NULL) return NULL; sig_file = tmpfile(); //创建签名文件 if(sig_file == NULL) { fclose(basis_file); return NULL; } ret = rs_sig_file(basis_file, sig_file, block_len, strong_len, &stats); fclose(basis_file); if(ret) { fclose(sig_file); return NULL; } fflush(sig_file); rewind(sig_file); return sig_file; }
bool rsync_sig(char* oldfile,char* sigfile){ FILE* old=FileUtil::rs_file_open(oldfile,"rb"); FILE* sig=FileUtil::rs_file_open(sigfile,"wb"); rs_result rs=rs_sig_file(old,sig,blk_len,stg_len,NULL); FileUtil::rs_file_close(old); FileUtil::rs_file_close(sig); if(rs==RS_DONE){ return true;}else{ return false;} }
/** * Generate signature from remaining command line arguments. */ static rs_result rdiff_sig(poptContext opcon) { FILE *basis_file, *sig_file; rs_stats_t stats; rs_result result; basis_file = rs_file_open(poptGetArg(opcon), "rb"); sig_file = rs_file_open(poptGetArg(opcon), "wb"); rdiff_no_more_args(opcon); result = rs_sig_file(basis_file, sig_file, block_len, strong_len, &stats); if (result != RS_DONE) return result; if (show_stats) rs_log_stats(&stats); return result; }
void csync_rs_sig(const char *filename) { FILE *basis_file = 0, *sig_file = 0; rs_stats_t stats; rs_result result; char tmpfname[MAXPATHLEN]; csync_debug(3, "Csync2 / Librsync: csync_rs_sig('%s')\n", filename); csync_debug(3, "Opening basis_file and sig_file..\n"); sig_file = open_temp_file(tmpfname, prefixsubst(filename)); if ( !sig_file ) goto io_error; if (unlink(tmpfname) < 0) goto io_error; basis_file = fopen(prefixsubst(filename), "rb"); if ( !basis_file ) basis_file = fopen("/dev/null", "rb"); csync_debug(3, "Running rs_sig_file() from librsync..\n"); result = rs_sig_file(basis_file, sig_file, RS_DEFAULT_BLOCK_LEN, RS_DEFAULT_STRONG_LEN, &stats); if (result != RS_DONE) csync_fatal("Got an error from librsync, too bad!\n"); csync_debug(3, "Sending sig_file to peer..\n"); csync_send_file(sig_file); csync_debug(3, "Signature has been created successfully.\n"); fclose(basis_file); fclose(sig_file); return; io_error: csync_debug(0, "I/O Error '%s' in rsync-sig: %s\n", strerror(errno), prefixsubst(filename)); if (basis_file) fclose(basis_file); if (sig_file) fclose(sig_file); }
int csync_rs_check(const char *filename, int isreg) { FILE *basis_file = 0, *sig_file = 0; char buffer1[512], buffer2[512]; int rc, chunk, found_diff = 0; int backup_errno; rs_stats_t stats; rs_result result; long size; char tmpfname[MAXPATHLEN]; csync_debug(3, "Csync2 / Librsync: csync_rs_check('%s', %d [%s])\n", filename, isreg, isreg ? "regular file" : "non-regular file"); csync_debug(3, "Opening basis_file and sig_file..\n"); sig_file = open_temp_file(tmpfname, prefixsubst(filename)); if ( !sig_file ) goto io_error; if (unlink(tmpfname) < 0) goto io_error; basis_file = fopen(prefixsubst(filename), "rb"); if ( !basis_file ) { /* ?? why a tmp file? */ basis_file = open_temp_file(tmpfname, prefixsubst(filename)); if ( !basis_file ) goto io_error; if (unlink(tmpfname) < 0) goto io_error; } if ( isreg ) { csync_debug(3, "Running rs_sig_file() from librsync....\n"); result = rs_sig_file(basis_file, sig_file, RS_DEFAULT_BLOCK_LEN, RS_DEFAULT_STRONG_LEN, &stats); if (result != RS_DONE) { csync_debug(0, "Internal error from rsync library!\n"); goto error; } } fclose(basis_file); basis_file = 0; { char line[100]; csync_debug(3, "Reading signature size from peer....\n"); if ( !conn_gets(line, 100) || sscanf(line, "octet-stream %ld\n", &size) != 1 ) csync_fatal("Format-error while receiving data.\n"); } fflush(sig_file); if ( size != ftell(sig_file) ) { csync_debug(2, "Signature size differs: local=%d, peer=%d\n", ftell(sig_file), size); found_diff = 1; } rewind(sig_file); csync_debug(3, "Receiving %ld bytes ..\n", size); while ( size > 0 ) { chunk = size > 512 ? 512 : size; rc = conn_read(buffer1, chunk); if ( rc <= 0 ) csync_fatal("Read-error while receiving data.\n"); chunk = rc; if ( fread(buffer2, chunk, 1, sig_file) != 1 ) { csync_debug(2, "Found EOF in local sig file.\n"); found_diff = 1; } if ( memcmp(buffer1, buffer2, chunk) ) { csync_debug(2, "Found diff in sig at -%d:-%d\n", size, size-chunk); found_diff = 1; } size -= chunk; csync_debug(3, "Got %d bytes, %ld bytes left ..\n", chunk, size); } csync_debug(3, "File has been checked successfully (%s).\n", found_diff ? "difference found" : "files are equal"); fclose(sig_file); return found_diff; io_error: csync_debug(0, "I/O Error '%s' in rsync-check: %s\n", strerror(errno), prefixsubst(filename)); error:; backup_errno = errno; if ( basis_file ) fclose(basis_file); if ( sig_file ) fclose(sig_file); errno = backup_errno; 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; }