librsync  2.3.4
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" /* IWYU pragma: keep */
31 #include <stdio.h>
32 #include <string.h>
33 #include "librsync.h"
34 #include "whole.h"
35 #include "sumset.h"
36 #include "job.h"
37 #include "buf.h"
38 #include "librsync_export.h"
39 
40 /** Whole file IO buffer sizes. */
41 LIBRSYNC_EXPORT int rs_inbuflen = 0, rs_outbuflen = 0;
42 
43 rs_result rs_whole_run(rs_job_t *job, FILE *in_file, FILE *out_file,
44  int inbuflen, int outbuflen)
45 {
46  rs_buffers_t buf;
47  rs_result result;
48  rs_filebuf_t *in_fb = NULL, *out_fb = NULL;
49 
50  /* Override buffer sizes if rs_inbuflen or rs_outbuflen are set. */
51  inbuflen = rs_inbuflen ? rs_inbuflen : inbuflen;
52  outbuflen = rs_outbuflen ? rs_outbuflen : outbuflen;
53  if (in_file)
54  in_fb = rs_filebuf_new(in_file, inbuflen);
55  if (out_file)
56  out_fb = rs_filebuf_new(out_file, outbuflen);
57  result =
58  rs_job_drive(job, &buf, in_fb ? rs_infilebuf_fill : NULL, in_fb,
59  out_fb ? rs_outfilebuf_drain : NULL, out_fb);
60  if (in_fb)
61  rs_filebuf_free(in_fb);
62  if (out_fb)
63  rs_filebuf_free(out_fb);
64  return result;
65 }
66 
67 rs_result rs_sig_file(FILE *old_file, FILE *sig_file, size_t block_len,
68  size_t strong_len, rs_magic_number sig_magic,
69  rs_stats_t *stats)
70 {
71  rs_job_t *job;
72  rs_result r;
73  rs_long_t old_fsize = rs_file_size(old_file);
74 
75  if ((r =
76  rs_sig_args(old_fsize, &sig_magic, &block_len,
77  &strong_len)) != RS_DONE)
78  return r;
79  job = rs_sig_begin(block_len, strong_len, sig_magic);
80  /* Size inbuf for 4 blocks, outbuf for header + 4 blocksums. */
81  r = rs_whole_run(job, old_file, sig_file, 4 * (int)block_len,
82  12 + 4 * (4 + (int)strong_len));
83  if (stats)
84  memcpy(stats, &job->stats, sizeof *stats);
85  rs_job_free(job);
86 
87  return r;
88 }
89 
90 rs_result rs_loadsig_file(FILE *sig_file, rs_signature_t **sumset,
91  rs_stats_t *stats)
92 {
93  rs_job_t *job;
94  rs_result r;
95 
96  job = rs_loadsig_begin(sumset);
97  /* Set filesize used to estimate signature size. */
98  job->sig_fsize = rs_file_size(sig_file);
99  /* Size inbuf for 1024x 16 byte blocksums. */
100  r = rs_whole_run(job, sig_file, NULL, 1024 * 16, 0);
101  if (stats)
102  memcpy(stats, &job->stats, sizeof *stats);
103  rs_job_free(job);
104 
105  return r;
106 }
107 
108 rs_result rs_delta_file(rs_signature_t *sig, FILE *new_file, FILE *delta_file,
109  rs_stats_t *stats)
110 {
111  rs_job_t *job;
112  rs_result r;
113 
114  job = rs_delta_begin(sig);
115  /* Size inbuf for 4*(CMD + 1 block), outbuf for 4*CMD. */
116  r = rs_whole_run(job, new_file, delta_file,
117  4 * (MAX_DELTA_CMD + sig->block_len), 4 * MAX_DELTA_CMD);
118  if (stats)
119  memcpy(stats, &job->stats, sizeof *stats);
120  rs_job_free(job);
121  return r;
122 }
123 
124 rs_result rs_patch_file(FILE *basis_file, FILE *delta_file, FILE *new_file,
125  rs_stats_t *stats)
126 {
127  rs_job_t *job;
128  rs_result r;
129 
130  job = rs_patch_begin(rs_file_copy_cb, basis_file);
131  /* Default size inbuf 1*CMD and outbuf 4*CMD. */
132  r = rs_whole_run(job, delta_file, new_file, MAX_DELTA_CMD,
133  4 * MAX_DELTA_CMD);
134  if (stats)
135  memcpy(stats, &job->stats, sizeof *stats);
136  rs_job_free(job);
137  return r;
138 }
Buffers that map between stdio file streams and librsync streams.
rs_job_t * rs_delta_begin(rs_signature_t *sig)
Prepare to compute a streaming delta.
Definition: delta.c:396
Generic state-machine interface.
#define MAX_DELTA_CMD
Max length of a singled delta command is including command bytes.
Definition: job.h:44
Public header for librsync.
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:135
LIBRSYNC_EXPORT rs_result rs_job_free(rs_job_t *)
Deallocate job state.
Definition: job.c:58
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:67
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:113
LIBRSYNC_EXPORT rs_long_t rs_file_size(FILE *file)
Get the size of a file.
Definition: fileutil.c:127
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:108
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:110
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:90
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:124
rs_result
Return codes from nonblocking rsync operations.
Definition: librsync.h:180
@ RS_DONE
Completed successfully.
Definition: librsync.h:181
LIBRSYNC_EXPORT 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:139
rs_magic_number
A uint32 magic number, emitted in bigendian/network order at the start of librsync files.
Definition: librsync.h:65
LIBRSYNC_EXPORT rs_result rs_file_copy_cb(void *arg, rs_long_t pos, size_t *len, void **buf)
rs_copy_cb that reads from a stdio file.
Definition: fileutil.c:135
LIBRSYNC_EXPORT int rs_inbuflen
Buffer sizes for file IO.
Definition: whole.c:41
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:221
Description of input and output buffers.
Definition: librsync.h:328
Definition: buf.c:37
The contents of this structure are private.
Definition: job.h:47
rs_long_t sig_fsize
The size of the signature file if available.
Definition: job.h:69
rs_stats_t stats
Encoding statistics.
Definition: job.h:93
Signature of a whole file.
Definition: sumset.h:44
int block_len
The block length.
Definition: sumset.h:46
Performance statistics from a librsync encoding or decoding operation.
Definition: librsync.h:210
The rs_signature class implementation of a file signature.
Whole-file API driver functions.
rs_result rs_whole_run(rs_job_t *job, FILE *in_file, FILE *out_file, int inbuflen, int outbuflen)
Run a job continuously, with input to/from the two specified files.
Definition: whole.c:43