librsync  2.0.1
readsums.c
Go to the documentation of this file.
1 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  *
3  * librsync -- the library for network deltas
4  *
5  * Copyright (C) 1999, 2000, 2001 by Martin Pool <[email protected]>
6  * Copyright (C) 1999 by Andrew Tridgell <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License 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 readsums.c
26  * \brief Load signatures from a file.
27  */
28 
29 #include "config.h"
30 
31 #include <assert.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 
36 #include "librsync.h"
37 #include "sumset.h"
38 #include "job.h"
39 #include "trace.h"
40 #include "netint.h"
41 #include "util.h"
42 #include "stream.h"
43 
44 
45 static rs_result rs_loadsig_s_weak(rs_job_t *job);
46 static rs_result rs_loadsig_s_strong(rs_job_t *job);
47 
48 
49 
50 /**
51  * Add a just-read-in checksum pair to the signature block.
52  */
53 static rs_result rs_loadsig_add_sum(rs_job_t *job, rs_strong_sum_t *strong)
54 {
55  size_t new_size;
56  rs_signature_t *sig = job->signature;
57  rs_block_sig_t *asignature;
58 
59  sig->count++;
60  new_size = sig->count * sizeof(rs_block_sig_t);
61 
62  sig->block_sigs = realloc(sig->block_sigs, new_size);
63 
64  if (sig->block_sigs == NULL) {
65  return RS_MEM_ERROR;
66  }
67  asignature = &(sig->block_sigs[sig->count - 1]);
68 
69  asignature->weak_sum = job->weak_sig;
70  asignature->i = sig->count;
71 
72  memcpy(asignature->strong_sum, strong, sig->strong_sum_len);
73 
74  if (rs_trace_enabled()) {
75  char hexbuf[RS_MAX_STRONG_SUM_LENGTH * 2 + 2];
76  rs_hexify(hexbuf, strong, sig->strong_sum_len);
77 
78  rs_trace("read in checksum: weak=%#x, strong=%s", asignature->weak_sum,
79  hexbuf);
80  }
81 
82  job->stats.sig_blocks++;
83 
84  return RS_RUNNING;
85 }
86 
87 
88 static rs_result rs_loadsig_s_weak(rs_job_t *job)
89 {
90  int l;
91  rs_result result;
92 
93  result = rs_suck_n4(job, &l);
94  if (result == RS_DONE)
95  ;
96  else if (result == RS_INPUT_ENDED) /* ending here is OK */
97  return RS_DONE;
98  else
99  return result;
100 
101  job->weak_sig = l;
102 
103  job->statefn = rs_loadsig_s_strong;
104 
105  return RS_RUNNING;
106 }
107 
108 
109 
110 static rs_result rs_loadsig_s_strong(rs_job_t *job)
111 {
112  rs_result result;
113  rs_strong_sum_t *strongsum;
114 
115  result = rs_scoop_read(job, job->signature->strong_sum_len,
116  (void **) &strongsum);
117  if (result != RS_DONE) return result;
118 
119  job->statefn = rs_loadsig_s_weak;
120 
121  return rs_loadsig_add_sum(job, strongsum);
122 }
123 
124 
125 
126 static rs_result rs_loadsig_s_stronglen(rs_job_t *job)
127 {
128  int l;
129  rs_result result;
130 
131  if ((result = rs_suck_n4(job, &l)) != RS_DONE)
132  return result;
133  job->strong_sum_len = l;
134 
135  if (l < 0 || l > RS_MAX_STRONG_SUM_LENGTH) {
136  rs_error("strong sum length %d is implausible", l);
137  return RS_CORRUPT;
138  }
139 
140  job->signature->block_len = job->block_len;
141  job->signature->strong_sum_len = job->strong_sum_len;
142 
143  rs_trace("allocated sigset_t (strong_sum_len=%d, block_len=%d)",
144  (int) job->strong_sum_len, (int) job->block_len);
145 
146  job->statefn = rs_loadsig_s_weak;
147 
148  return RS_RUNNING;
149 }
150 
151 
152 static rs_result rs_loadsig_s_blocklen(rs_job_t *job)
153 {
154  int l;
155  rs_result result;
156 
157  if ((result = rs_suck_n4(job, &l)) != RS_DONE)
158  return result;
159  job->block_len = l;
160 
161  if (job->block_len < 1) {
162  rs_error("block length of %d is bogus", (int) job->block_len);
163  return RS_CORRUPT;
164  }
165 
166  job->statefn = rs_loadsig_s_stronglen;
167  job->stats.block_len = job->block_len;
168 
169  return RS_RUNNING;
170 }
171 
172 
173 static rs_result rs_loadsig_s_magic(rs_job_t *job)
174 {
175  int l;
176  rs_result result;
177 
178  if ((result = rs_suck_n4(job, &l)) != RS_DONE) {
179  return result;
180  }
181 
182  switch(l) {
183  case RS_MD4_SIG_MAGIC:
184  case RS_BLAKE2_SIG_MAGIC:
185  job->magic = job->signature->magic = l;
186  rs_trace("got signature magic %#10x", l);
187  break;
188  default:
189  rs_error("wrong magic number %#10x for signature", l);
190  return RS_BAD_MAGIC;
191  }
192 
193  job->statefn = rs_loadsig_s_blocklen;
194 
195  return RS_RUNNING;
196 }
197 
198 
200 {
201  rs_job_t *job;
202 
203  job = rs_job_new("loadsig", rs_loadsig_s_magic);
204  *signature = job->signature = rs_alloc_struct(rs_signature_t);
205  job->signature->count = 0;
206 
207  return job;
208 }
A signature file using the BLAKE2 hash.
Definition: librsync.h:106
rs_job_t * rs_loadsig_begin(rs_signature_t **signature)
Read a signature from a file into an rs_signature structure in memory.
Definition: readsums.c:199
Out of memory.
Definition: librsync.h:204
Bad magic number at start of stream.
Definition: librsync.h:208
rs_long_t sig_blocks
Number of blocks described by the signature.
Definition: librsync.h:247
rs_signature_t * signature
Signature that&#39;s either being read in, or used for generating a delta.
Definition: job.h:51
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
Unbelievable value in stream.
Definition: librsync.h:214
rs_weak_sum_t weak_sig
The weak signature digest used by readsums.c.
Definition: job.h:57
A signature file with MD4 signatures.
Definition: librsync.h:97
rs_result(* statefn)(rs_job_t *)
Callback for each processing step.
Definition: job.h:38
rs_stats_t stats
Encoding statistics.
Definition: job.h:69
Public header for librsync.
rs_result
Return codes from nonblocking rsync operations.
Definition: librsync.h:192
Unexpected end of input file, perhaps due to a truncated file or dropped network connection.
Definition: librsync.h:207
The job is still running, and not yet finished or blocked.
Definition: librsync.h:198
Completed successfully.
Definition: librsync.h:193
The contents of this structure are private.
Definition: job.h:29