#include "config.h"
#include <assert.h>
#include <stdlib.h>
#include "librsync.h"
#include "job.h"
#include "sumset.h"
#include "stream.h"
#include "netint.h"
#include "trace.h"
#include "util.h"
static rs_result rs_sig_s_header(rs_job_t *);
static rs_result rs_sig_s_generate(rs_job_t *);
static rs_result rs_sig_s_header(rs_job_t *job)
{
rs_signature_t *sig = job->signature;
rs_result result;
if ((result =
rs_signature_init(sig, job->sig_magic, job->sig_block_len,
job->sig_strong_len, 0)) != RS_DONE)
return result;
rs_squirt_n4(job, sig->magic);
rs_squirt_n4(job, sig->block_len);
rs_squirt_n4(job, sig->strong_sum_len);
rs_trace("sent header (magic %#x, block len = %d, strong sum len = %d)",
sig->magic, sig->block_len, sig->strong_sum_len);
job->stats.block_len = sig->block_len;
job->statefn = rs_sig_s_generate;
return RS_RUNNING;
}
static rs_result rs_sig_do_block(rs_job_t *job, const void *block, size_t len)
{
rs_signature_t *sig = job->signature;
rs_weak_sum_t weak_sum;
rs_strong_sum_t strong_sum;
weak_sum = rs_signature_calc_weak_sum(sig, block, len);
rs_signature_calc_strong_sum(sig, block, len, &strong_sum);
rs_squirt_n4(job, weak_sum);
rs_tube_write(job, strong_sum, sig->strong_sum_len);
if (rs_trace_enabled()) {
char strong_sum_hex[RS_MAX_STRONG_SUM_LENGTH * 2 + 1];
rs_hexify(strong_sum_hex, strong_sum, sig->strong_sum_len);
rs_trace("sent block: weak=" FMT_WEAKSUM ", strong=%s", weak_sum,
strong_sum_hex);
}
job->stats.sig_blocks++;
return RS_RUNNING;
}
static rs_result rs_sig_s_generate(rs_job_t *job)
{
rs_result result;
size_t len;
void *block;
len = job->signature->block_len;
result = rs_scoop_read(job, len, &block);
if (result == RS_INPUT_ENDED)
result = rs_scoop_read_rest(job, &len, &block);
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 " FMT_SIZE " byte block", len);
return rs_sig_do_block(job, block, len);
}
rs_job_t *rs_sig_begin(size_t new_block_len, size_t strong_sum_len,
rs_magic_number sig_magic)
{
rs_job_t *job;
job = rs_job_new("signature", rs_sig_s_header);
job->signature = rs_alloc_struct(rs_signature_t);
job->job_owns_sig = 1;
job->sig_magic = sig_magic;
job->sig_block_len = new_block_len;
job->sig_strong_len = strong_sum_len;
return job;
}