static rs_result rs_whole_gzrun(rs_job_t *job, FILE *in_file, gzFile in_zfile, FILE *out_file, gzFile out_zfile, struct cntr *cntr) { rs_buffers_t buf; rs_result result; rs_filebuf_t *in_fb = NULL, *out_fb = NULL; if (in_file || in_zfile) in_fb = rs_filebuf_new(NULL, in_file, in_zfile, -1, ASYNC_BUF_LEN, -1, cntr); if (out_file || out_zfile) out_fb = rs_filebuf_new(NULL, out_file, out_zfile, -1, ASYNC_BUF_LEN, -1, cntr); //logp("before drive\n"); result = rs_job_drive(job, &buf, in_fb ? rs_infilebuf_fill : NULL, in_fb, out_fb ? rs_outfilebuf_drain : NULL, out_fb); //logp("after drive\n"); if (in_fb) rs_filebuf_free(in_fb); if (out_fb) rs_filebuf_free(out_fb); return result; }
/** * Run a job continuously, with input to/from the two specified files. * The job should already be set up, and must be free by the caller * after return. * * Buffers of ::rs_inbuflen and ::rs_outbuflen are allocated for * temporary storage. * * \param in_file Source of input bytes, or NULL if the input buffer * should not be filled. * * \return RS_DONE if the job completed, or otherwise an error result. */ rs_result rs_whole_run(rs_job_t *job, FILE *in_file, FILE *out_file) { rs_buffers_t buf; rs_result result; rs_filebuf_t *in_fb = NULL, *out_fb = NULL; if (in_file) in_fb = rs_filebuf_new(in_file, rs_inbuflen); if (out_file) out_fb = rs_filebuf_new(out_file, rs_outbuflen); result = rs_job_drive(job, &buf, in_fb ? rs_infilebuf_fill : NULL, in_fb, out_fb ? rs_outfilebuf_drain : NULL, out_fb); if (in_fb) rs_filebuf_free(in_fb); if (out_fb) rs_filebuf_free(out_fb); return result; }
executer_result _executer_send_signature (executer_job_t * job) { rs_job_t *sigjob; executer_rs inrs; executer_rs outrs; rs_buffers_t rsbuf; utils_debug ("Sending signature"); int openfile = open (job->realpath, O_RDONLY); inrs.sock = openfile; inrs.type = _EXECUTER_FILE; inrs.size = RS_DEFAULT_BLOCK_LEN; inrs.buf = malloc (inrs.size); outrs.sock = job->peer_sock; outrs.type = _EXECUTER_SOCKET; outrs.size = _EXECUTER_DEFAULT_OUT; outrs.buf = malloc (outrs.size); sigjob = rs_sig_begin (RS_DEFAULT_BLOCK_LEN, RS_DEFAULT_STRONG_LEN); rs_result result = rs_job_drive (sigjob, &rsbuf, _executer_in_callback, &inrs, _executer_out_callback, &outrs); // Free the memory rs_job_free (sigjob); free (inrs.buf); free (outrs.buf); close (openfile); if (result != RS_DONE) { utils_error ("Error sending signature"); return EXECUTER_ERROR; } _executer_send_finish (job->peer_sock); job->next_operation = _executer_recive_delta; return EXECUTER_RUNNING; }
rs_result do_rs_run(rs_job_t *job, BFILE *bfd, FILE *in_file, FILE *out_file, gzFile in_zfile, gzFile out_zfile, int infd, int outfd, struct cntr *cntr) { rs_buffers_t buf; rs_result result; rs_filebuf_t *in_fb=NULL; rs_filebuf_t *out_fb=NULL; if(in_file && infd>=0) { logp("do not specify both input file and input fd in do_rs_run()\n"); return RS_IO_ERROR; } if(out_file && outfd>=0) { logp("do not specify both output file and output fd in do_rs_run()\n"); return RS_IO_ERROR; } if((bfd || in_file || in_zfile || infd>=0) && !(in_fb=rs_filebuf_new(bfd, in_file, in_zfile, infd, ASYNC_BUF_LEN, -1, cntr))) return RS_MEM_ERROR; if((out_file || out_zfile || outfd>=0) && !(out_fb=rs_filebuf_new(NULL, out_file, out_zfile, outfd, ASYNC_BUF_LEN, -1, cntr))) { if(in_fb) rs_filebuf_free(in_fb); return RS_MEM_ERROR; } //logp("before rs_job_drive\n"); result = rs_job_drive(job, &buf, in_fb ? rs_infilebuf_fill : NULL, in_fb, out_fb ? rs_outfilebuf_drain : NULL, out_fb); //logp("after rs_job_drive\n"); if(in_fb) rs_filebuf_free(in_fb); if(out_fb) rs_filebuf_free(out_fb); return result; }
rs_result rs_loadsig_network_run(struct asfd *asfd, rs_job_t *job, struct cntr *cntr) { rs_buffers_t buf; rs_result result; rs_filebuf_t *in_fb=NULL; if(!(in_fb=rs_filebuf_new(asfd, NULL, NULL, asfd->fd, ASYNC_BUF_LEN, -1, cntr))) { result=RS_MEM_ERROR; goto end; } result=rs_job_drive(job, &buf, rs_infilebuf_fill, in_fb, NULL, NULL); end: rs_filebuf_free(&in_fb); return result; }
executer_result _executer_recive_signature (executer_job_t * job) { rs_signature_t *signature; rs_job_t *signature_job; executer_rs inrs; rs_result result; rs_buffers_t rsbuf; utils_debug ("Receiving signature"); //Load the signature signature_job = rs_loadsig_begin (&signature); inrs.type = _EXECUTER_SOCKET; inrs.sock = job->peer_sock; inrs.size = RS_DEFAULT_BLOCK_LEN; inrs.buf = malloc (inrs.size); // Run librsync job result = rs_job_drive (signature_job, &rsbuf, _executer_in_callback, &inrs, NULL, NULL); // Free the memory rs_job_free (signature_job); free (inrs.buf); if (result != RS_DONE) { utils_error ("Error carculating singnature"); return EXECUTER_ERROR; } else { //After receive signature, we need send delta job->next_operation = _executer_send_delta; job->signature = signature; return EXECUTER_RUNNING; } }
static rs_result rs_whole_gzrun(struct asfd *asfd, rs_job_t *job, struct fzp *in_file, struct fzp *out_file, struct cntr *cntr) { rs_buffers_t buf; rs_result result; rs_filebuf_t *in_fb=NULL; rs_filebuf_t *out_fb=NULL; if(in_file) in_fb=rs_filebuf_new(asfd, NULL, in_file, -1, ASYNC_BUF_LEN, -1, cntr); if(out_file) out_fb=rs_filebuf_new(asfd, NULL, out_file, -1, ASYNC_BUF_LEN, -1, cntr); result=rs_job_drive(job, &buf, in_fb ? rs_infilebuf_fill : NULL, in_fb, out_fb ? rs_outfilebuf_drain : NULL, out_fb); rs_filebuf_free(&in_fb); rs_filebuf_free(&out_fb); return result; }
executer_result _executer_send_delta (executer_job_t * job) { // The opaque pointer is to signature rs_signature_t *signature = job->signature; rs_job_t *deltajob; char *realpath; executer_rs inrs; executer_rs outrs; rs_result result; rs_buffers_t rsbuf; utils_debug ("Sending delta data"); deltajob = rs_delta_begin (signature); _executer_real_path (job->file, &realpath); int file2 = open (realpath, O_RDONLY); inrs.type = _EXECUTER_FILE; inrs.sock = file2; inrs.size = RS_DEFAULT_BLOCK_LEN; inrs.buf = malloc (inrs.size); outrs.type = _EXECUTER_SOCKET; outrs.sock = job->peer_sock; outrs.size = _EXECUTER_DEFAULT_OUT; outrs.buf = malloc (outrs.size); if (rs_build_hash_table (signature) != RS_DONE) { utils_error ("Error building hash table"); return EXECUTER_ERROR; } result = rs_job_drive (deltajob, &rsbuf, _executer_in_callback, &inrs, _executer_out_callback, &outrs); // Free the memory free (realpath); rs_job_free (deltajob); free (inrs.buf); free (outrs.buf); // Send finish to the socket if (!_executer_send_finish (job->peer_sock)) { utils_error ("Error sending finish message: %s", strerror (errno)); return EXECUTER_ERROR; } if (result != RS_DONE) { utils_error ("Error calculating delta"); return EXECUTER_ERROR; } else { // Ok, send the stat job->next_operation = _executer_send_stat; // Ok, the delta is send, no need more process return EXECUTER_RUNNING; } }
executer_result _executer_recive_delta (executer_job_t * job) { char *temppath; rs_buffers_t rsbuf; executer_rs inrs; executer_rs outrs; int result; utils_debug ("Receving delta."); int tempfile = _executer_create_temp (job->realpath, &temppath); if (tempfile == 0) { utils_error ("Error creating temp file for file '%s': %s", job->realpath, strerror (errno)); return EXECUTER_ERROR; } FILE *origfile = fopen (job->realpath, "rb"); if (origfile == NULL) { utils_error ("Error opening file '%s': %s", job->realpath, strerror (errno)); return EXECUTER_ERROR; } rs_job_t *patchjob = rs_patch_begin (rs_file_copy_cb, origfile); inrs.sock = job->peer_sock; inrs.type = _EXECUTER_SOCKET; inrs.size = _EXECUTER_DEFAULT_OUT; inrs.buf = malloc (inrs.size); outrs.sock = tempfile; outrs.type = _EXECUTER_FILE; outrs.size = RS_DEFAULT_BLOCK_LEN; outrs.buf = malloc (outrs.size); rsbuf.avail_in = 0; rsbuf.avail_out = 0; rsbuf.next_in = 0; rsbuf.next_out = 0; rsbuf.eof_in = false; result = rs_job_drive (patchjob, &rsbuf, _executer_in_callback, &inrs, _executer_out_callback, &outrs); if (result != RS_DONE) { utils_error ("Error patching file"); return EXECUTER_ERROR; } //Check if there are any data if (rsbuf.avail_out > 0) { _executer_in_callback (patchjob, &rsbuf, &inrs); _executer_out_callback (patchjob, &rsbuf, &outrs); } rs_job_free (patchjob); close (tempfile); fclose (origfile); free (outrs.buf); free (inrs.buf); job->next_operation = _executer_receive_stat; job->tempfile = temppath; return EXECUTER_RUNNING; }