librsync  2.0.2
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 Generate file signatures.
24  *
25  * Generating checksums is pretty easy, since we can always just process
26  * whatever data is available. When a whole block has arrived, or we've reached
27  * the end of the file, we write the checksum out.
28  *
29  * \todo Perhaps force blocks to be a multiple of 64 bytes, so that we can be
30  * sure checksum generation will be more efficient. I guess it will be OK at
31  * the moment, though, because tails are only used if necessary. */
32 
33 #include "config.h"
34 
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <assert.h>
38 
39 #include "librsync.h"
40 #include "stream.h"
41 #include "util.h"
42 #include "sumset.h"
43 #include "job.h"
44 #include "netint.h"
45 #include "trace.h"
46 
47 /* Possible state functions for signature generation. */
50 
51 /** State of trying to send the signature header. \private */
53 {
54  rs_signature_t *sig = job->signature;
55  rs_result result;
56 
57  if ((result =
58  rs_signature_init(sig, job->sig_magic, job->sig_block_len,
59  job->sig_strong_len, 0)) != RS_DONE)
60  return result;
61  rs_squirt_n4(job, sig->magic);
62  rs_squirt_n4(job, sig->block_len);
63  rs_squirt_n4(job, sig->strong_sum_len);
64  rs_trace("sent header (magic %#x, block len = %d, strong sum len = %d)",
65  sig->magic, sig->block_len, sig->strong_sum_len);
66  job->stats.block_len = sig->block_len;
67 
69  return RS_RUNNING;
70 }
71 
72 /** Generate the checksums for a block and write it out. Called when we
73  * already know we have enough data in memory at \p block. \private */
74 static rs_result rs_sig_do_block(rs_job_t *job, const void *block, size_t len)
75 {
76  rs_signature_t *sig = job->signature;
77  rs_weak_sum_t weak_sum;
78  rs_strong_sum_t strong_sum;
79 
80  weak_sum = rs_calc_weak_sum(block, len);
81  rs_signature_calc_strong_sum(sig, block, len, &strong_sum);
82  rs_squirt_n4(job, weak_sum);
83  rs_tube_write(job, strong_sum, sig->strong_sum_len);
84  if (rs_trace_enabled()) {
85  char strong_sum_hex[RS_MAX_STRONG_SUM_LENGTH * 2 + 1];
86  rs_hexify(strong_sum_hex, strong_sum, sig->strong_sum_len);
87  rs_trace("sent block: weak=" FMT_WEAKSUM ", strong=%s", weak_sum,
88  strong_sum_hex);
89  }
90  job->stats.sig_blocks++;
91  return RS_RUNNING;
92 }
93 
94 /** State of reading a block and trying to generate its sum. \private */
96 {
97  rs_result result;
98  size_t len;
99  void *block;
100 
101  /* must get a whole block, otherwise try again */
102  len = job->signature->block_len;
103  result = rs_scoop_read(job, len, &block);
104  /* If we are near EOF, get whatever is left. */
105  if (result == RS_INPUT_ENDED)
106  result = rs_scoop_read_rest(job, &len, &block);
107  if (result == RS_INPUT_ENDED) {
108  return RS_DONE;
109  } else if (result != RS_DONE) {
110  rs_trace("generate stopped: %s", rs_strerror(result));
111  return result;
112  }
113  rs_trace("got " FMT_SIZE " byte block", len);
114  return rs_sig_do_block(job, block, len);
115 }
116 
117 rs_job_t *rs_sig_begin(size_t new_block_len, size_t strong_sum_len,
118  rs_magic_number sig_magic)
119 {
120  rs_job_t *job;
121 
122  job = rs_job_new("signature", rs_sig_s_header);
123  job->signature = rs_alloc_struct(rs_signature_t);
124  job->job_owns_sig = 1;
125  job->sig_magic = sig_magic;
126  job->sig_block_len = new_block_len;
127  job->sig_strong_len = strong_sum_len;
128  return job;
129 }
logging functions.
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:208
int block_len
The block length.
Definition: sumset.h:39
rs_long_t sig_blocks
Number of blocks described by the signature.
Definition: librsync.h:203
rs_signature_t * signature
Pointer to the signature that's being used by the operation.
Definition: job.h:51
int job_owns_sig
Flag indicating signature should be destroyed with the job.
Definition: job.h:54
void rs_hexify(char *to_buf, void const *from_buf, int from_len)
Convert from_len bytes at from_buf into a hex representation in to_buf, which must be twice as long p...
Definition: hex.c:32
int strong_sum_len
The block strong sum length.
Definition: sumset.h:40
static rs_result rs_sig_s_generate(rs_job_t *)
State of reading a block and trying to generate its sum.
Definition: mksum.c:95
rs_result(* statefn)(rs_job_t *)
Callback for each processing step.
Definition: job.h:35
rs_stats_t stats
Encoding statistics.
Definition: job.h:72
Public header for librsync.
Signature of a whole file.
Definition: sumset.h:37
char const * rs_strerror(rs_result r)
Return an English description of a rs_result value.
Definition: msg.c:49
rs_result
Return codes from nonblocking rsync operations.
Definition: librsync.h:161
Unexpected end of input file, perhaps due to a truncated file or dropped network connection.
Definition: librsync.h:171
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:190
int magic
The signature magic value.
Definition: sumset.h:38
rs_magic_number
A uint32 magic number, emitted in bigendian/network order at the start of librsync files.
Definition: librsync.h:68
rs_job_t * rs_sig_begin(size_t new_block_len, size_t strong_sum_len, rs_magic_number sig_magic)
Start generating a signature.
Definition: mksum.c:117
The job is still running, and not yet finished or blocked.
Definition: librsync.h:164
Completed successfully.
Definition: librsync.h:162
void rs_tube_write(rs_job_t *job, const void *buf, size_t len)
Push some data into the tube for storage.
Definition: tube.c:211
static rs_result rs_sig_s_header(rs_job_t *)
State of trying to send the signature header.
Definition: mksum.c:52
of this structure are private.
Definition: job.h:26