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