18 typedef enum rs_result {RS_DONE} rs_result;
20 size_t sig_inbytes, sig_outbytes, sig_zinbytes, sig_zoutbytes;
23 char *next_in; /**< Next input byte */
24 size_t avail_in; /**< Number of bytes available at next_in */
25 int eof_in; /**< True if there is no more data
28 char *next_out; /**< Next output byte should be put there */
29 size_t avail_out; /**< Remaining free space at next_out */
32 static ssize_t sig_writebuf(void *private, char *buf, size_t len)
34 struct mem_buf *bofs = (struct mem_buf *)private;
36 if (bofs->length != -1) {
37 len = MIN(len, bofs->length - bofs->ofs);
40 memcpy(bofs->buf+bofs->ofs, buf, len);
45 static ssize_t sig_readbuf(void *private, char *buf, size_t len)
47 struct mem_buf *bofs = (struct mem_buf *)private;
49 if (bofs->length != -1) {
50 len = MIN(len, bofs->length - bofs->ofs);
53 memcpy(buf, bofs->buf+bofs->ofs, len);
58 static ssize_t sig_readfn(void *private, char *buf, size_t len)
60 struct file_buf *fbuf = (struct file_buf *)private;
64 if (fbuf->length == 0) {
69 if (fbuf->length == -1) {
70 n = fread(buf, 1, len, fbuf->f);
72 if (n > 0 && fbuf->f_cache) {
73 fwrite(buf, 1, n, fbuf->f_cache);
78 len2 = MIN(len, fbuf->length);
80 n = fread(buf, 1, len2, fbuf->f);
90 if (n > 0 && fbuf->f_cache) {
91 fwrite(buf, 1, n, fbuf->f_cache);
101 static ssize_t sig_zreadfn(void *private, char *buf, size_t len)
105 ret = decomp_read(sig_readfn, private, buf, len);
112 static ssize_t sig_writefn(void *private, char *buf, size_t len)
114 struct file_buf *fbuf = (struct file_buf *)private;
117 n = fwrite(buf, 1, len, fbuf->f);
118 if (fbuf->f_cache && n > 0) {
119 fwrite(buf, 1, n, fbuf->f_cache);
127 static ssize_t sig_zwritefn(void *private, char *buf, size_t len)
131 ret = comp_write(sig_writefn, private, buf, len);
133 sig_zoutbytes += ret;
138 static ssize_t sig_readfn_ofs(void *private, char *buf, size_t len, off_t ofs)
140 struct file_buf *fbuf = (struct file_buf *)private;
144 fseek(fbuf->f, ofs, SEEK_SET);
145 n = fread(buf, 1, len, fbuf->f);
151 static rs_result rsig_readfn(rs_job_t *job, rs_buffers_t *buf,
154 struct file_buf *fbuf = (struct file_buf *)opaque;
165 len = sig_readfn(fbuf, fbuf->buf, sizeof(fbuf->buf));
175 buf->next_in = fbuf->buf;
181 static rs_result rsig_zreadfn(rs_job_t *job, rs_buffers_t *buf,
184 struct file_buf *fbuf = (struct file_buf *)opaque;
195 len = sig_zreadfn(fbuf, fbuf->buf, sizeof(fbuf->buf));
205 buf->next_in = fbuf->buf;
211 rs_result rsig_writebuf(rs_job_t *job, rs_buffers_t *buf, void *opaque)
213 struct mem_buf *mbuf = (struct mem_buf *)opaque;
215 if (buf->next_out == NULL) {
216 buf->next_out = mbuf->buf;
217 buf->avail_out = mbuf->length;
221 mbuf->ofs = buf->next_out - mbuf->buf;
222 if (mbuf->ofs >= mbuf->length) {
226 buf->avail_out = mbuf->length - mbuf->ofs;
232 /* generate the signatures for a file putting them in a sigblock,
233 and return a pointer to the sigblock, which must be base64 encoded */
234 char *sig_generate(FILE *f)
241 struct file_buf fbuf;
245 if (fstat(fileno(f), &st)) {
246 errmsg("fstat error in sig_generate\n");
250 block_size = (st.st_size / (MAX_SIG_SIZE/(8+8))) & ~15;
251 if (block_size < 128) block_size = 128;
253 buf = (char *)xmalloc(MAX_SIG_SIZE*2);
254 buf2 = (char *)xmalloc(MAX_SIG_SIZE*2); /* plenty of extra space */
258 mbuf.length = MAX_SIG_SIZE*2;
264 sig_inbytes = sig_outbytes = sig_zinbytes = sig_zoutbytes = 0;
266 memset(&rbuf, 0, sizeof(rbuf));
268 job = rs_sig_begin(block_size, 8);
269 r = rs_job_drive(job, &rbuf,
270 rsig_readfn, (void *)&fbuf,
271 rsig_writebuf, (void *)&mbuf);
274 base64_encode((unsigned char *)buf, mbuf.ofs, buf2);
276 logmsg("generated signature of size %u block_size=%d inbytes=%d\n",
277 (unsigned)mbuf.ofs, block_size, sig_inbytes);
284 static rs_result rsig_readfn_ofs(void *opaque, off_t pos,
285 size_t *len, void **buf)
289 ret = sig_readfn_ofs(opaque, *buf, *len, pos);
299 rs_result rsig_writefn(rs_job_t *job, rs_buffers_t *buf, void *opaque)
301 struct file_buf *fbuf = (struct file_buf *)opaque;
304 if (buf->next_out == NULL) {
305 buf->next_out = fbuf->buf;
306 buf->avail_out = sizeof(fbuf->buf);
310 present = buf->next_out - fbuf->buf;
313 int ret = sig_writefn(fbuf, fbuf->buf, present);
316 buf->next_out = fbuf->buf;
317 buf->avail_out = sizeof(fbuf->buf);
322 rs_result rsig_zwritefn(rs_job_t *job, rs_buffers_t *buf, void *opaque)
324 struct file_buf *fbuf = (struct file_buf *)opaque;
327 if (buf->next_out == NULL) {
328 buf->next_out = fbuf->buf;
329 buf->avail_out = sizeof(fbuf->buf);
333 present = buf->next_out - fbuf->buf;
336 int ret = sig_zwritefn(fbuf, fbuf->buf, present);
339 buf->next_out = fbuf->buf;
340 buf->avail_out = sizeof(fbuf->buf);
345 /* decode a rsync-encoded file stream, putting the decoded data to
346 f_out and f_cache. The file used to generate the signature is
347 available in f_orig */
348 void sig_decode(FILE *f_in, FILE *f_out, FILE *f_orig, FILE *f_cache,
349 ssize_t content_length)
352 struct file_buf fbuf_orig, fbuf_out, fbuf_in;
356 fbuf_orig.f = f_orig;
357 fbuf_orig.f_cache = NULL;
358 fbuf_orig.length = -1;
359 fbuf_orig.fn = sig_readfn_ofs;
362 fbuf_out.f_cache = f_cache;
363 fbuf_out.length = -1;
364 fbuf_out.fn = sig_writefn;
367 fbuf_in.f_cache = NULL;
368 fbuf_in.length = content_length;
369 fbuf_in.fn = sig_readfn;
371 sig_inbytes = sig_outbytes = 0;
373 memset(&rbuf, 0, sizeof(rbuf));
377 job = rs_patch_begin(rsig_readfn_ofs, &fbuf_orig);
378 r = rs_job_drive(job, &rbuf,
379 rsig_zreadfn, (void *)&fbuf_in,
380 rsig_writefn, (void *)&fbuf_out);
383 logmsg("librsync_decode->%d (in=%d out=%d)\n",
384 (int)r, (int)sig_inbytes, (int)sig_outbytes);
388 rs_result rsig_readbuf(rs_job_t *job, rs_buffers_t *buf, void *opaque)
390 struct mem_buf *mbuf = (struct mem_buf *)opaque;
392 if (buf->next_in == NULL) {
393 buf->next_in = mbuf->buf;
394 buf->avail_in = mbuf->length;
398 if (buf->avail_in == 0) {
408 /* encode a file stream, putting the encoded data to f_out and the
409 unencoded data to f_cache. The signature of the original file is in
410 signature, in base64 form */
411 void sig_encode(FILE *f_in, FILE *f_out, char *signature, FILE *f_cache,
412 ssize_t content_length)
415 struct file_buf fbuf_r, fbuf_w;
423 sig2 = xstrdup(signature);
424 sig_length = base64_decode(sig2);
427 fbuf_r.f_cache = f_cache;
428 fbuf_r.length = content_length;
430 logmsg("sig_encode content_length=%d sig_length=%u\n",
431 content_length, sig_length);
434 fbuf_w.f_cache = NULL;
439 mbuf.length = sig_length;
441 sig_inbytes = sig_outbytes = 0;
443 memset(&rbuf, 0, sizeof(rbuf));
445 job = rs_loadsig_begin(&sig);
446 r = rs_job_drive(job, &rbuf,
447 rsig_readbuf, (void *)&mbuf,
452 memset(&rbuf, 0, sizeof(rbuf));
454 r = rs_build_hash_table(sig);
458 job = rs_delta_begin(sig);
459 r = rs_job_drive(job, &rbuf,
460 rsig_readfn, (void *)&fbuf_r,
461 rsig_zwritefn, (void *)&fbuf_w);
464 comp_flush(sig_writefn, (void *)&fbuf_w);
467 logmsg("librsync_encode->%d (in=%d out=%d)\n",
468 (int)r, (int)sig_inbytes, (int)sig_outbytes);