librsync  2.3.3
mksum.c
Go to the documentation of this file.
1/*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 *
3 * librsync -- library for network deltas
4 *
5 * Copyright 1999-2001, 2014, 2015 by Martin Pool <mbp@sourcefrog.net>
6 * Copyright (C) 1999 by Andrew Tridgell <tridge@samba.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23/** \file mksum.c
24 * Generate file signatures.
25 *
26 * Generating checksums is pretty easy, since we can always just process
27 * whatever data is available. When a whole block has arrived, or we've reached
28 * the end of the file, we write the checksum out. */
29
30#include <stdlib.h>
31#include "librsync.h"
32#include "job.h"
33#include "sumset.h"
34#include "scoop.h"
35#include "netint.h"
36#include "trace.h"
37#include "util.h"
38
39/* Possible state functions for signature generation. */
42
43/** State of trying to send the signature header. \private */
45{
46 rs_signature_t *sig = job->signature;
47 rs_result result;
48
49 if ((result =
50 rs_signature_init(sig, job->sig_magic, job->sig_block_len,
51 job->sig_strong_len, 0)) != RS_DONE)
52 return result;
53 rs_squirt_n4(job, sig->magic);
54 rs_squirt_n4(job, sig->block_len);
55 rs_squirt_n4(job, sig->strong_sum_len);
56 rs_trace("sent header (magic %#x, block len = %d, strong sum len = %d)",
57 sig->magic, sig->block_len, sig->strong_sum_len);
58 job->stats.block_len = sig->block_len;
59
61 return RS_RUNNING;
62}
63
64/** Generate the checksums for a block and write it out. Called when we
65 * already know we have enough data in memory at \p block. \private */
66static rs_result rs_sig_do_block(rs_job_t *job, const void *block, size_t len)
67{
68 rs_signature_t *sig = job->signature;
69 rs_weak_sum_t weak_sum;
70 rs_strong_sum_t strong_sum;
71
72 weak_sum = rs_signature_calc_weak_sum(sig, block, len);
73 rs_signature_calc_strong_sum(sig, block, len, &strong_sum);
74 rs_squirt_n4(job, weak_sum);
75 rs_tube_write(job, strong_sum, sig->strong_sum_len);
76 if (rs_trace_enabled()) {
77 char strong_sum_hex[RS_MAX_STRONG_SUM_LENGTH * 2 + 1];
78 rs_hexify(strong_sum_hex, strong_sum, sig->strong_sum_len);
79 rs_trace("sent block: weak=" FMT_WEAKSUM ", strong=%s", weak_sum,
80 strong_sum_hex);
81 }
82 job->stats.sig_blocks++;
83 return RS_RUNNING;
84}
85
86/** State of reading a block and trying to generate its sum. \private */
88{
89 rs_result result;
90 size_t len;
91 void *block;
92
93 /* must get a whole block, otherwise try again */
94 len = job->signature->block_len;
95 result = rs_scoop_read(job, len, &block);
96 /* If we are near EOF, get whatever is left. */
97 if (result == RS_INPUT_ENDED)
98 result = rs_scoop_read_rest(job, &len, &block);
99 if (result == RS_INPUT_ENDED) {
100 return RS_DONE;
101 } else if (result != RS_DONE) {
102 rs_trace("generate stopped: %s", rs_strerror(result));
103 return result;
104 }
105 rs_trace("got " FMT_SIZE " byte block", len);
106 return rs_sig_do_block(job, block, len);
107}
108
109rs_job_t *rs_sig_begin(size_t block_len, size_t strong_len,
110 rs_magic_number sig_magic)
111{
112 rs_job_t *job;
113
114 job = rs_job_new("signature", rs_sig_s_header);
116 job->job_owns_sig = 1;
117 job->sig_magic = sig_magic;
118 job->sig_block_len = (int)block_len;
119 job->sig_strong_len = (int)strong_len;
120 return job;
121}
Generic state-machine interface.
Public header for librsync.
LIBRSYNC_EXPORT char const * rs_strerror(rs_result r)
Return an English description of a rs_result value.
Definition: msg.c:45
rs_result
Return codes from nonblocking rsync operations.
Definition: librsync.h:180
@ RS_RUNNING
The job is still running, and not yet finished or blocked.
Definition: librsync.h:183
@ RS_DONE
Completed successfully.
Definition: librsync.h:181
@ RS_INPUT_ENDED
Unexpected end of input file, perhaps due to a truncated file or dropped network connection.
Definition: librsync.h:190
rs_magic_number
A uint32 magic number, emitted in bigendian/network order at the start of librsync files.
Definition: librsync.h:65
rs_job_t * rs_sig_begin(size_t block_len, size_t strong_len, rs_magic_number sig_magic)
Start generating a signature.
Definition: mksum.c:109
static rs_result rs_sig_s_generate(rs_job_t *)
State of reading a block and trying to generate its sum.
Definition: mksum.c:87
static rs_result rs_sig_s_header(rs_job_t *)
State of trying to send the signature header.
Definition: mksum.c:44
Network-byte-order output to the tube.
rs_result rs_scoop_read(rs_job_t *job, size_t len, void **ptr)
Read LEN bytes if possible, and remove them from the input scoop.
Definition: scoop.c:191
rs_result rs_scoop_read_rest(rs_job_t *job, size_t *len, void **ptr)
Read whatever data remains in the input stream.
Definition: scoop.c:211
Manage librsync streams of IO.
void rs_tube_write(rs_job_t *job, void const *buf, size_t len)
Push some data into the tube for storage.
Definition: tube.c:173
The contents of this structure are private.
Definition: job.h:47
int job_owns_sig
Flag indicating signature should be destroyed with the job.
Definition: job.h:75
rs_result(* statefn)(rs_job_t *)
Callback for each processing step.
Definition: job.h:56
rs_signature_t * signature
Pointer to the signature that's being used by the operation.
Definition: job.h:72
rs_stats_t stats
Encoding statistics.
Definition: job.h:93
Signature of a whole file.
Definition: sumset.h:44
int magic
The signature magic value.
Definition: sumset.h:45
int block_len
The block length.
Definition: sumset.h:46
int strong_sum_len
The block strong sum length.
Definition: sumset.h:47
rs_long_t sig_blocks
Number of blocks described by the signature.
Definition: librsync.h:222
The rs_signature class implementation of a file signature.
static rs_weak_sum_t rs_signature_calc_weak_sum(rs_signature_t const *sig, void const *buf, size_t len)
Calculate the weak sum of a buffer.
Definition: sumset.h:128
static void rs_signature_calc_strong_sum(rs_signature_t const *sig, void const *buf, size_t len, rs_strong_sum_t *sum)
Calculate the strong sum of a buffer.
Definition: sumset.h:136
logging functions.
#define rs_trace_enabled()
Call this before putting too much effort into generating trace messages.
Definition: trace.h:73
Misc utility functions used by librsync.
#define rs_alloc_struct(type)
Allocate and zero-fill an instance of TYPE.
Definition: util.h:41