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 <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
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  * Add a just-read-in checksum pair to the signature block.
50  */
51 static rs_result rs_loadsig_add_sum(rs_job_t *job, rs_strong_sum_t *strong)
52 {
53  rs_signature_t *sig = job->signature;
54 
55  if (rs_trace_enabled()) {
56  char hexbuf[RS_MAX_STRONG_SUM_LENGTH * 2 + 2];
57  rs_hexify(hexbuf, strong, sig->strong_sum_len);
58  rs_trace("got block: weak=%#x, strong=%s", job->weak_sig, hexbuf);
59  }
60  rs_signature_add_block(job->signature, job->weak_sig, strong);
61  job->stats.sig_blocks++;
62  return RS_RUNNING;
63 }
64 
65 
66 static rs_result rs_loadsig_s_weak(rs_job_t *job)
67 {
68  int l;
69  rs_result result;
70 
71  if ((result = rs_suck_n4(job, &l)) != RS_DONE) {
72  if (result == RS_INPUT_ENDED) /* ending here is OK */
73  return RS_DONE;
74  return result;
75  }
76  job->weak_sig = l;
77  job->statefn = rs_loadsig_s_strong;
78  return RS_RUNNING;
79 }
80 
81 
82 static rs_result rs_loadsig_s_strong(rs_job_t *job)
83 {
84  rs_result result;
85  rs_strong_sum_t *strongsum;
86 
87  if ((result = rs_scoop_read(job, job->signature->strong_sum_len, (void **)&strongsum)) != RS_DONE)
88  return result;
89  job->statefn = rs_loadsig_s_weak;
90  return rs_loadsig_add_sum(job, strongsum);
91 }
92 
93 
94 
95 static rs_result rs_loadsig_s_stronglen(rs_job_t *job)
96 {
97  int l;
98  rs_result result;
99 
100  if ((result = rs_suck_n4(job, &l)) != RS_DONE)
101  return result;
102  if (l < 0 || l > RS_MAX_STRONG_SUM_LENGTH) {
103  rs_error("strong sum length %d is implausible", l);
104  return RS_CORRUPT;
105  }
106  rs_trace("got strong sum length %d", l);
107  job->sig_strong_len = l;
108  /* Initialize the signature. */
109  if ((result = rs_signature_init(job->signature, job->sig_magic,
110  job->sig_block_len, job->sig_strong_len,
111  job->sig_fsize)) != RS_DONE)
112  return result;
113  job->statefn = rs_loadsig_s_weak;
114  return RS_RUNNING;
115 }
116 
117 
118 static rs_result rs_loadsig_s_blocklen(rs_job_t *job)
119 {
120  int l;
121  rs_result result;
122 
123  if ((result = rs_suck_n4(job, &l)) != RS_DONE)
124  return result;
125  if (l < 1) {
126  rs_error("block length of %d is bogus", l);
127  return RS_CORRUPT;
128  }
129  rs_trace("got block length %d", l);
130  job->sig_block_len = l;
131  job->stats.block_len = l;
132  job->statefn = rs_loadsig_s_stronglen;
133  return RS_RUNNING;
134 }
135 
136 
137 static rs_result rs_loadsig_s_magic(rs_job_t *job)
138 {
139  int l;
140  rs_result result;
141 
142  if ((result = rs_suck_n4(job, &l)) != RS_DONE)
143  return result;
144  rs_trace("got signature magic %#10x", l);
145  job->sig_magic = l;
146  job->statefn = rs_loadsig_s_blocklen;
147  return RS_RUNNING;
148 }
149 
150 
152 {
153  rs_job_t *job;
154 
155  job = rs_job_new("loadsig", rs_loadsig_s_magic);
156  *signature = job->signature = rs_alloc_struct(rs_signature_t);
157  return job;
158 }
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:151
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
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:215
rs_weak_sum_t weak_sig
The weak signature digest used by readsums.c.
Definition: job.h:63
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
rs_long_t sig_fsize
The size of the signature file if available.
Definition: job.h:51
Public header for librsync.
Signature of a whole file.
Definition: sumset.h:39
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
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