Esempio n. 1
0
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;
}
Esempio n. 2
0
/*
 * State of reading a block and trying to generate its sum.
 */
static rs_result
rs_sig_s_generate(rs_job_t *job)
{
    rs_result           result;
    size_t              len;
    void                *block;
        
    /* must get a whole block, otherwise try again */
    len = job->block_len;
    result = rs_scoop_read(job, len, &block);
        
    /* unless we're near eof, in which case we'll accept
     * whatever's in there */
    if ((result == RS_BLOCKED && rs_job_input_is_ending(job))) {
        result = rs_scoop_read_rest(job, &len, &block);
    } else if (result == RS_INPUT_ENDED) {
        return RS_DONE;
    } else if (result != RS_DONE) {
        rs_trace("generate stopped: %s", rs_strerror(result));
        return result;
    }

    rs_trace("got %ld byte block", (long) len);

    return rs_sig_do_block(job, block, len);
}
Esempio n. 3
0
int main(int argc, char *argv[])
{
	FILE *basis_file;
	FILE *delta_file;
	rs_result ret;
	FILE *new_file;
	rs_stats_t stats;

	if(argc != 4)
	{
		fprintf(stderr, "invalid argument(s)\n");
		exit(1);
	}

	basis_file = fopen(argv[1], "rb");
	delta_file = fopen(argv[2], "rb");
	new_file = fopen(argv[3], "wb");

	ret = rs_patch_file(basis_file, delta_file, new_file, &stats);
	fclose(basis_file);
	fclose(delta_file);
	fclose(new_file);
	if(ret != RS_DONE)
	{
		puts(rs_strerror(ret));
		exit(1);
	}
	rs_log_stats(&stats);
	return 0;
}
Esempio n. 4
0
static ERL_NIF_TERM format_error(ErlNifEnv* env, int argc,
				 const ERL_NIF_TERM argv[])
{
  unsigned len;
  int res;

  if (!enif_get_atom_length(env, argv[0], &len, ERL_NIF_LATIN1))
    return enif_make_badarg(env);

  char *atom = malloc(len+1);
  if (!enif_get_atom(env, argv[0], atom, len+1, ERL_NIF_LATIN1)) {
    free(atom);
    return enif_make_badarg(env);
  }

  if (!strcmp("done", atom)) res = RS_DONE;
  else if (!strcmp("blocked", atom)) res = RS_BLOCKED;
  else if (!strcmp("running", atom)) res = RS_RUNNING;
  else if (!strcmp("test_skipped", atom)) res = RS_TEST_SKIPPED;
  else if (!strcmp("io_error", atom)) res = RS_IO_ERROR;
  else if (!strcmp("syntax_error", atom)) res = RS_SYNTAX_ERROR;
  else if (!strcmp("mem_error", atom)) res = RS_MEM_ERROR;
  else if (!strcmp("input_ended", atom)) res = RS_INPUT_ENDED;
  else if (!strcmp("bad_magic", atom)) res = RS_BAD_MAGIC;
  else if (!strcmp("unimplemented", atom)) res = RS_UNIMPLEMENTED;
  else if (!strcmp("corrupt", atom)) res = RS_CORRUPT;
  else if (!strcmp("internal_error", atom)) res = RS_INTERNAL_ERROR;
  else if (!strcmp("param_error", atom)) res = RS_PARAM_ERROR;
  else res = -1;

  free(atom);

  return enif_make_string(env, rs_strerror(res), ERL_NIF_LATIN1);
}
Esempio n. 5
0
// Also used by restore.c.
// FIX THIS: This stuff is very similar to make_rev_delta, can maybe share
// some code.
int do_patch(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;

	if((result=rs_patch_gzfile(dstp, delfzp, upfzp))!=RS_DONE)
	{
		logp("rs_patch_gzfile returned %d %s\n",
			result, rs_strerror(result));
	}
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;
}
Esempio n. 6
0
int main(const int argc, const char *argv[])
{
    poptContext     opcon;
    rs_result       result;

    opcon = poptGetContext(PROGRAM, argc, argv, opts, 0);
    rdiff_options(opcon);
    result = rdiff_action(opcon);

    if (result != RS_DONE)
        rs_log(RS_LOG_ERR|RS_LOG_NONAME, "%s", rs_strerror(result));

    return result;
}
Esempio n. 7
0
/**
 * Called when we're executing a COPY command and waiting for all the
 * data to be retrieved from the callback.
 */
static rs_result rs_patch_s_copying(rs_job_t *job)
{
    rs_result       result;
    size_t          desired_len, len;
    void            *ptr;
    rs_buffers_t    *buffs = job->stream;

    /* copy only as much as will fit in the output buffer, so that we
     * don't have to block or store the input. */
    desired_len = len = (buffs->avail_out < job->basis_len) ? buffs->avail_out : job->basis_len;

    if (!len)
        return RS_BLOCKED;

    rs_trace("copy " PRINTF_FORMAT_U64 " bytes from basis at offset " PRINTF_FORMAT_U64 "",
             PRINTF_CAST_U64(len), PRINTF_CAST_U64(job->basis_pos));

    ptr = buffs->next_out;

    result = (job->copy_cb)(job->copy_arg, job->basis_pos, &len, &ptr);
    if (result != RS_DONE)
        return result;
    else
        rs_trace("copy callback returned %s", rs_strerror(result));

    rs_trace("got " PRINTF_FORMAT_U64 " bytes back from basis callback", PRINTF_CAST_U64(len));

    if (len > desired_len) {
        rs_trace("warning: copy_cb returned more than the requested length.");
        len = desired_len;
    }

    /* copy back to out buffer only if the callback has used its own buffer */
    if (ptr != buffs->next_out)
        memcpy(buffs->next_out, ptr, len);

    buffs->next_out += len;
    buffs->avail_out -= len;

    job->basis_pos += len;
    job->basis_len -= len;

    if (!job->basis_len) {
        /* Done! */
        job->statefn = rs_patch_s_cmdbyte;
    }

    return RS_RUNNING;
}
Esempio n. 8
0
/**
 * Called when we're executing a COPY command and waiting for all the
 * data to be retrieved from the callback.
 */
static rs_result rs_patch_s_copying(rs_job_t *job)
{
    rs_result       result;
    size_t          len;
    void            *buf, *ptr;
    rs_buffers_t    *buffs = job->stream;

    len = job->basis_len;
    
    /* copy only as much as will fit in the output buffer, so that we
     * don't have to block or store the input. */
    if (len > buffs->avail_out)
        len = buffs->avail_out;

    if (!len)
        return RS_BLOCKED;

    rs_trace("copy " PRINTF_FORMAT_U64 " bytes from basis at offset " PRINTF_FORMAT_U64 "",
             PRINTF_CAST_U64(len), PRINTF_CAST_U64(job->basis_pos));

    ptr = buf = rs_alloc(len, "basis buffer");
    
    result = (job->copy_cb)(job->copy_arg, job->basis_pos, &len, &ptr);
    if (result != RS_DONE)
        return result;
    else
        rs_trace("copy callback returned %s", rs_strerror(result));
    
    rs_trace("got " PRINTF_FORMAT_U64 " bytes back from basis callback", PRINTF_CAST_U64(len));

    memcpy(buffs->next_out, ptr, len);

    buffs->next_out += len;
    buffs->avail_out -= len;

    job->basis_pos += len;
    job->basis_len -= len;

    free(buf);

    if (!job->basis_len) {
        /* Done! */
        job->statefn = rs_patch_s_cmdbyte;
    } 

    return RS_RUNNING;
}
Esempio n. 9
0
static rs_result rs_job_complete(rs_job_t *job, rs_result result)
{
    rs_job_check(job);
    
    job->statefn = rs_job_s_complete;
    job->final_result = result;

    if (result != RS_DONE) {
        rs_error("%s job failed: %s", job->job_name, rs_strerror(result));
    } else {
        rs_trace("%s job complete", job->job_name);
    }

    if (result == RS_DONE && !rs_tube_is_idle(job))
        /* Processing is finished, but there is still some data
         * waiting to get into the output buffer. */
        return RS_BLOCKED;
    else
        return result;
}
Esempio n. 10
0
static int make_rev_sig(const char *dst, const char *sig, const char *endfile,
	int compression, struct conf **confs)
{
	int ret=-1;
	rs_result result;
	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")))
		goto end;
	
	if((result=rs_sig_gzfile(dstfzp, sigp,
		get_librsync_block_len(endfile),
		PROTO1_RS_STRONG_LEN, confs)!=RS_DONE))
	{
		logp("rs_sig_gzfile returned %d %s\n",
			result, rs_strerror(result));
		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;
}
Esempio n. 11
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);
}