コード例 #1
0
ファイル: emit.c プロジェクト: Estevo-Aleixo/librsync
/** Write a COPY command for given offset and length.
 *
 * There is a choice of variable-length encodings, depending on the
 * size of representation for the parameters. */
void
rs_emit_copy_cmd(rs_job_t *job, rs_long_t where, rs_long_t len)
{
    int            cmd;
    rs_stats_t     *stats = &job->stats;
    const int where_bytes = rs_int_len(where);
    const int len_bytes   = rs_int_len(len);

    /* Commands ascend (1,1), (1,2), ... (8, 8) */
    if (where_bytes == 8) 
        cmd = RS_OP_COPY_N8_N1;
    else if (where_bytes == 4)
        cmd = RS_OP_COPY_N4_N1;
    else if (where_bytes == 2)
        cmd = RS_OP_COPY_N2_N1;
    else if (where_bytes == 1)
        cmd = RS_OP_COPY_N1_N1;
    else {
        rs_fatal("can't encode copy command with where_bytes=%d",
                 where_bytes);
    }

    if (len_bytes == 1)
        ;
    else if (len_bytes == 2)
        cmd += 1;
    else if (len_bytes == 4)
        cmd += 2;
    else if (len_bytes == 8)
        cmd += 3;
    else {
        rs_fatal("can't encode copy command with len_bytes=%d",
                 len_bytes);
    }       

    rs_trace("emit COPY_N%d_N%d(where=" PRINTF_FORMAT_U64
             ", len=" PRINTF_FORMAT_U64 "), cmd_byte=%#x",
             where_bytes, len_bytes, PRINTF_CAST_U64(where), PRINTF_CAST_U64(len), cmd);
    rs_squirt_byte(job, cmd);
    rs_squirt_netint(job, where, where_bytes);
    rs_squirt_netint(job, len, len_bytes);

    stats->copy_cmds++;
    stats->copy_bytes += len;
    stats->copy_cmdbytes += 1 + where_bytes + len_bytes;

    /* TODO: All the stats */
}
コード例 #2
0
ファイル: emit.c プロジェクト: opieproject/opie
/* Write a LITERAL command. */
void
rs_emit_literal_cmd(rs_job_t *job, int len)
{
    int cmd;
    int param_len;

    switch (param_len = rs_int_len(len)) {
    case 1:
        cmd = RS_OP_LITERAL_N1;
        break;
    case 2:
        cmd = RS_OP_LITERAL_N2;
        break;
    case 4:
        cmd = RS_OP_LITERAL_N4;
        break;
    default:
        rs_fatal("What?");
    }

    rs_trace("emit LITERAL_N%d(len=%d), cmd_byte=%#x", param_len, len, cmd);
    rs_squirt_byte(job, cmd);
    rs_squirt_netint(job, len, param_len);

    job->stats.lit_cmds++;
    job->stats.lit_bytes += len;
    job->stats.lit_cmdbytes += 1 + param_len;
}
コード例 #3
0
ファイル: util.c プロジェクト: DrWrong/librsync
void *
rs_alloc(size_t size, char const *name)
{
    void           *p;

    if (!(p = malloc(size))) {
        rs_fatal("couldn't allocate instance of %s", name);
    }

    return p;
}
コード例 #4
0
ファイル: delta.c プロジェクト: Tongbupan/librsync
/**
 * \brief Get a block of data if possible, and see if it matches.
 * 
 * On each call, we try to process all of the input data available on the
 * scoop and input buffer. */
static rs_result rs_delta_s_scan(rs_job_t *job)
{
    rs_long_t      match_pos;
    size_t         match_len;
    rs_result      result;
    Rollsum        test;

    rs_job_check(job);
    /* read the input into the scoop */
    rs_getinput(job);
    /* output any pending output from the tube */
    result=rs_tube_catchup(job);
    /* while output is not blocked and there is a block of data */
    while ((result==RS_DONE) && 
           ((job->scoop_pos + job->block_len) < job->scoop_avail)) {
        /* check if this block matches */
        if (rs_findmatch(job,&match_pos,&match_len)) {
            /* append the match and reset the weak_sum */
            result=rs_appendmatch(job,match_pos,match_len);
            RollsumInit(&job->weak_sum);
        } else {
            /* rotate the weak_sum and append the miss byte */
            RollsumRotate(&job->weak_sum,job->scoop_next[job->scoop_pos],
                          job->scoop_next[job->scoop_pos+job->block_len]);
            result=rs_appendmiss(job,1);
            if (rs_roll_paranoia) {
                RollsumInit(&test);
                RollsumUpdate(&test,job->scoop_next+job->scoop_pos,
                              job->block_len);
                if (RollsumDigest(&test) != RollsumDigest(&job->weak_sum)) {
                    rs_fatal("mismatch between rolled sum %#x and check %#x",
                             (int)RollsumDigest(&job->weak_sum),
                             (int)RollsumDigest(&test));
                }
                
            }
        }
    }
    /* if we completed OK */
    if (result==RS_DONE) {
        /* if we reached eof, we can flush the last fragment */
        if (job->stream->eof_in) {
            job->statefn=rs_delta_s_flush;
            return RS_RUNNING;
        } else {
            /* we are blocked waiting for more data */
            return RS_BLOCKED;
        }
    }
    return result;
}
コード例 #5
0
ファイル: search.c プロジェクト: potatogim/librsync
/* 
 * See if there is a match for the specified block INBUF..BLOCK_LEN in
 * the checksum set, using precalculated WEAK_SUM.
 *
 * If we don't find a match on the weak checksum, then we just give
 * up.  If we do find a weak match, then we proceed to calculate the
 * strong checksum for the current block, and see if it will match
 * anything.
 */
int
rs_search_for_block(rs_weak_sum_t weak_sum,
                    const rs_byte_t *inbuf,
                    size_t block_len,
                    rs_signature_t const *sig, rs_stats_t * stats,
                    rs_long_t * match_where)
{
    /* Caller must have called rs_build_hash_table() by now */
    if (!sig->tag_table)
        rs_fatal("Must have called rs_build_hash_table() by now");

    rs_strong_sum_t strong_sum;
    int got_strong = 0;
    int hash_tag = gettag(weak_sum);
    rs_tag_table_entry_t *bucket = &(sig->tag_table[hash_tag]);
    int l = bucket->l;
    int r = bucket->r + 1;
    int v = 1;

    if (l == NULL_TAG)
	return 0;

    while (l < r) {
	int m = (l + r) >> 1;
	int i = sig->targets[m].i;
	rs_block_sig_t *b = &(sig->block_sigs[i]);
	v = (weak_sum > b->weak_sum) - (weak_sum < b->weak_sum); // v < 0  - weak_sum <  b->weak_sum
								 // v == 0 - weak_sum == b->weak_sum
								 // v > 0  - weak_sum >  b->weak_sum
	if (v == 0) {
	    if (!got_strong) {
		if(sig->magic == RS_BLAKE2_SIG_MAGIC) {
		    rs_calc_blake2_sum(inbuf, block_len, &strong_sum);
		} else if (sig->magic == RS_MD4_SIG_MAGIC) {
		    rs_calc_md4_sum(inbuf, block_len, &strong_sum);
		} else {
		    rs_error("Unknown signature algorithm - this is a BUG");
		    return 0; /* FIXME: Is this the best way to handle this? */
		}
		got_strong = 1;
	    }
	    v = memcmp(strong_sum, b->strong_sum, sig->strong_sum_len);

	    if (v == 0) {
		l = m;
		r = m;
		break;
	    }
	}

	if (v > 0)
	    l = m + 1;
	else
	    r = m;
    }

    if (l == r) {
	int i = sig->targets[l].i;
	rs_block_sig_t *b = &(sig->block_sigs[i]);
	if (weak_sum != b->weak_sum)
	    return 0;
	if (!got_strong) {
            if(sig->magic == RS_BLAKE2_SIG_MAGIC) {
	        rs_calc_blake2_sum(inbuf, block_len, &strong_sum);
	    } else if (sig->magic == RS_MD4_SIG_MAGIC) {
                rs_calc_md4_sum(inbuf, block_len, &strong_sum);
	    } else {
	        rs_error("Unknown signature algorithm - this is a BUG");
		return 0; /* FIXME: Is this the best way to handle this? */
	    }
	    got_strong = 1;
	}
	v = memcmp(strong_sum, b->strong_sum, sig->strong_sum_len);
	int token = b->i;
	*match_where = (rs_long_t)(token - 1) * sig->block_len;
    }

    return !v;
}
コード例 #6
0
ファイル: job.c プロジェクト: Salamek/librsync
static rs_result rs_job_s_complete(rs_job_t *job)
{
    rs_fatal("should not be reached");
    return RS_INTERNAL_ERROR;
}