librsync  2.3.2
whole.c
1/*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 *
3 * librsync -- the library for network deltas
4 *
5 * Copyright 2000, 2001, 2014, 2015 by Martin Pool <mbp@sourcefrog.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 /*=
23 | Is it possible that software is not
24 | like anything else, that it is meant
25 | to be discarded: that the whole point
26 | is to always see it as a soap bubble?
27 | -- Alan Perlis
28 */
29
30#include "config.h"
31#include <assert.h>
32#include <stdlib.h>
33#include <stdio.h>
34#include <string.h>
35#include "librsync.h"
36#include "whole.h"
37#include "sumset.h"
38#include "job.h"
39#include "buf.h"
40
41/** Whole file IO buffer sizes. */
42LIBRSYNC_EXPORT int rs_inbuflen = 0, rs_outbuflen = 0;
43
44/** Run a job continuously, with input to/from the two specified files.
45 *
46 * The job should already be set up, and must be freed by the caller after
47 * return. If rs_inbuflen or rs_outbuflen are set, they will override the
48 * inbuflen and outbuflen arguments.
49 *
50 * \param in_file - input file, or NULL if there is no input.
51 *
52 * \param out_file - output file, or NULL if there is no output.
53 *
54 * \param inbuflen - recommended input buffer size to use.
55 *
56 * \param outbuflen - recommended output buffer size to use.
57 *
58 * \return RS_DONE if the job completed, or otherwise an error result. */
59rs_result rs_whole_run(rs_job_t *job, FILE *in_file, FILE *out_file,
60 int inbuflen, int outbuflen)
61{
62 rs_buffers_t buf;
63 rs_result result;
64 rs_filebuf_t *in_fb = NULL, *out_fb = NULL;
65
66 /* Override buffer sizes if rs_inbuflen or rs_outbuflen are set. */
67 inbuflen = rs_inbuflen ? rs_inbuflen : inbuflen;
68 outbuflen = rs_outbuflen ? rs_outbuflen : outbuflen;
69 if (in_file)
70 in_fb = rs_filebuf_new(in_file, inbuflen);
71 if (out_file)
72 out_fb = rs_filebuf_new(out_file, outbuflen);
73 result =
74 rs_job_drive(job, &buf, in_fb ? rs_infilebuf_fill : NULL, in_fb,
75 out_fb ? rs_outfilebuf_drain : NULL, out_fb);
76 if (in_fb)
77 rs_filebuf_free(in_fb);
78 if (out_fb)
79 rs_filebuf_free(out_fb);
80 return result;
81}
82
83rs_result rs_sig_file(FILE *old_file, FILE *sig_file, size_t block_len,
84 size_t strong_len, rs_magic_number sig_magic,
85 rs_stats_t *stats)
86{
87 rs_job_t *job;
88 rs_result r;
89 rs_long_t old_fsize = rs_file_size(old_file);
90
91 if ((r =
92 rs_sig_args(old_fsize, &sig_magic, &block_len,
93 &strong_len)) != RS_DONE)
94 return r;
95 job = rs_sig_begin(block_len, strong_len, sig_magic);
96 /* Size inbuf for 4 blocks, outbuf for header + 4 blocksums. */
97 r = rs_whole_run(job, old_file, sig_file, 4 * (int)block_len,
98 12 + 4 * (4 + (int)strong_len));
99 if (stats)
100 memcpy(stats, &job->stats, sizeof *stats);
101 rs_job_free(job);
102
103 return r;
104}
105
106rs_result rs_loadsig_file(FILE *sig_file, rs_signature_t **sumset,
107 rs_stats_t *stats)
108{
109 rs_job_t *job;
110 rs_result r;
111
112 job = rs_loadsig_begin(sumset);
113 /* Set filesize used to estimate signature size. */
114 job->sig_fsize = rs_file_size(sig_file);
115 /* Size inbuf for 1024x 16 byte blocksums. */
116 r = rs_whole_run(job, sig_file, NULL, 1024 * 16, 0);
117 if (stats)
118 memcpy(stats, &job->stats, sizeof *stats);
119 rs_job_free(job);
120
121 return r;
122}
123
124rs_result rs_delta_file(rs_signature_t *sig, FILE *new_file, FILE *delta_file,
125 rs_stats_t *stats)
126{
127 rs_job_t *job;
128 rs_result r;
129
130 job = rs_delta_begin(sig);
131 /* Size inbuf for 1 block, outbuf for literal cmd + 4 blocks. */
132 r = rs_whole_run(job, new_file, delta_file, sig->block_len,
133 10 + 4 * sig->block_len);
134 if (stats)
135 memcpy(stats, &job->stats, sizeof *stats);
136 rs_job_free(job);
137 return r;
138}
139
140rs_result rs_patch_file(FILE *basis_file, FILE *delta_file, FILE *new_file,
141 rs_stats_t *stats)
142{
143 rs_job_t *job;
144 rs_result r;
145
146 job = rs_patch_begin(rs_file_copy_cb, basis_file);
147 /* Default size inbuf and outbuf 64K. */
148 r = rs_whole_run(job, delta_file, new_file, 64 * 1024, 64 * 1024);
149 if (stats)
150 memcpy(stats, &job->stats, sizeof *stats);
151 rs_job_free(job);
152 return r;
153}
rs_job_t * rs_delta_begin(rs_signature_t *sig)
Prepare to compute a streaming delta.
Definition: delta.c:386
rs_result rs_job_free(rs_job_t *job)
Deallocate job state.
Definition: job.c:66
rs_result rs_job_drive(rs_job_t *job, rs_buffers_t *buf, rs_driven_cb in_cb, void *in_opaque, rs_driven_cb out_cb, void *out_opaque)
Actively process a job, by making callbacks to fill and empty the buffers until the job is done.
Definition: job.c:152
Public header for librsync.
LIBRSYNC_EXPORT rs_job_t * rs_patch_begin(rs_copy_cb *copy_cb, void *copy_arg)
Apply a delta to a basis file to recreate the new file.
Definition: patch.c:217
LIBRSYNC_EXPORT 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:111
LIBRSYNC_EXPORT rs_result rs_sig_file(FILE *old_file, FILE *sig_file, size_t block_len, size_t strong_len, rs_magic_number sig_magic, rs_stats_t *stats)
Generate the signature of a basis file, and write it out to another.
Definition: whole.c:83
LIBRSYNC_EXPORT rs_result rs_sig_args(rs_long_t old_fsize, rs_magic_number *magic, size_t *block_len, size_t *strong_len)
Get or check signature arguments for a given file size.
Definition: sumset.c:114
LIBRSYNC_EXPORT rs_job_t * rs_loadsig_begin(rs_signature_t **)
Read a signature from a file into an rs_signature structure in memory.
Definition: readsums.c:137
LIBRSYNC_EXPORT rs_result rs_delta_file(rs_signature_t *, FILE *new_file, FILE *delta_file, rs_stats_t *)
Generate a delta between a signature and a new file into a delta file.
Definition: whole.c:124
LIBRSYNC_EXPORT rs_result rs_loadsig_file(FILE *sig_file, rs_signature_t **sumset, rs_stats_t *stats)
Load signatures from a signature file into memory.
Definition: whole.c:106
LIBRSYNC_EXPORT rs_result rs_patch_file(FILE *basis_file, FILE *delta_file, FILE *new_file, rs_stats_t *)
Apply a patch, relative to a basis, into a new file.
Definition: whole.c:140
rs_result
Return codes from nonblocking rsync operations.
Definition: librsync.h:180
@ RS_DONE
Completed successfully.
Definition: librsync.h:181
rs_magic_number
A uint32 magic number, emitted in bigendian/network order at the start of librsync files.
Definition: librsync.h:65
LIBRSYNC_EXPORT int rs_inbuflen
Buffer sizes for file IO.
Definition: whole.c:42
Description of input and output buffers.
Definition: librsync.h:322
Definition: buf.c:50
The contents of this structure are private.
Definition: job.h:26
rs_long_t sig_fsize
The size of the signature file if available.
Definition: job.h:48
rs_stats_t stats
Encoding statistics.
Definition: job.h:72
Signature of a whole file.
Definition: sumset.h:37
int block_len
The block length.
Definition: sumset.h:39
Performance statistics from a librsync encoding or decoding operation.
Definition: librsync.h:210