summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pool <mbp@sourcefrog.net>2001-02-07 23:24:41 +0000
committerMartin Pool <mbp@sourcefrog.net>2001-02-07 23:24:41 +0000
commit51114f4d0169297d540373705f6f3d014bc4b2a3 (patch)
treeef423d9c280f7e77cf6a3e46b35598674d0842b6
parent819e089b8437e909f5362230057914ecbc672c6d (diff)
downloadlibrsync-51114f4d0169297d540373705f6f3d014bc4b2a3.tar.gz
Change to a generic hs_job_t class so we can share the iterator code.
Drop HSFILE interface; not very useful at the moment. Therefore we could drop streamfile and other over-complex code as well. Doc. Generate strong checksums as well as weak; update the test case to reflect this. Drop leading underscores on function names; they're not proving very useful. rdiff/rsum are currently broken, but I wanted to commit the new library interface anyhow. Started changing towards libpopt.
-rw-r--r--Makefile.am28
-rw-r--r--TODO3
-rw-r--r--acconfig.h2
-rwxr-xr-xautogen.sh6
-rw-r--r--base64.c2
-rw-r--r--buf.c176
-rw-r--r--buf.h31
-rw-r--r--checksum.c11
-rw-r--r--checksum.h4
-rw-r--r--codeheader.c2
-rw-r--r--command.c8
-rw-r--r--command.h2
-rw-r--r--config.h15
-rw-r--r--configure.in20
-rw-r--r--copyq.c12
-rw-r--r--delta.c85
-rw-r--r--emit.c16
-rw-r--r--emit.h4
-rw-r--r--file.c258
-rw-r--r--file.h1
-rw-r--r--fileutil.c14
-rw-r--r--fileutil.h6
-rw-r--r--hex.c4
-rw-r--r--hsync.h71
-rw-r--r--hsyncfile.h6
-rw-r--r--job.c95
-rw-r--r--job.h49
-rw-r--r--mdfour.c24
-rwxr-xr-xmkprototab.sh2
-rw-r--r--mksum.c117
-rw-r--r--mksum.h2
-rw-r--r--mksum.input/COPYING.sigbin56 -> 160 bytes
-rw-r--r--netint.c42
-rw-r--r--netint.h18
-rw-r--r--patch.c162
-rw-r--r--prototab.h2
-rw-r--r--rdiff.c184
-rw-r--r--readsums.c126
-rw-r--r--rollsum.c10
-rw-r--r--rollsum.h6
-rw-r--r--rsum.c138
-rw-r--r--scoop.c48
-rw-r--r--search.c14
-rw-r--r--search.h2
-rw-r--r--snprintf.c2
-rw-r--r--stats.c2
-rw-r--r--stream.c45
-rw-r--r--stream.h34
-rw-r--r--streamfile.c113
-rw-r--r--sumset.c142
-rw-r--r--sumset.h28
-rw-r--r--trace.c42
-rw-r--r--trace.h34
-rw-r--r--tube.c28
-rw-r--r--util.c16
-rw-r--r--util.h12
-rw-r--r--version.c43
-rw-r--r--whole.c187
-rw-r--r--whole.h (renamed from streamfile.h)7
59 files changed, 1323 insertions, 1240 deletions
diff --git a/Makefile.am b/Makefile.am
index ec8c571..e83ac22 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
-# Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+# Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
# $Id$
# This program is free software; you can redistribute it and/or
@@ -28,31 +28,31 @@ lib_LTLIBRARIES = libhsync.la
libhsync_la_SOURCES = \
base64.c \
+ buf.c buf.h \
checksum.c checksum.h \
command.c command.h \
- delta.c delta.h \
+ delta.c \
emit.c emit.h \
- file.c \
fileutil.c fileutil.h \
hex.c \
hsync.h \
hsyncfile.h \
+ job.c job.h \
mdfour.c \
mksum.c \
msg.c \
netint.c netint.h \
patch.c \
- private.h \
protocol.h \
prototab.c prototab.h \
scoop.c \
stream.c stream.h \
- streamfile.c streamfile.h \
+ sumset.c \
trace.c trace.h \
- tube.c tube.h \
+ tube.c \
util.c util.h \
version.c \
- whole.c
+ whole.c whole.h
# TODO: If we ever care enough, build a second library containing only
# the code necessary to be a client, and not stuff for encoding. At
@@ -68,7 +68,8 @@ libhsync_la_SOURCES = \
# TODO: driver.sh requires bash. Therefore we should either test for
# it and use it rather than $SHELL, or we should rewrite it to work in
-# plain Bourne shell.
+# plain Bourne shell. Or perhaps we should use bash enforcing POSIX
+# compliance, so that we can detect and avoid such dependencies.
TESTS_ENVIRONMENT = bash $(srcdir)/driver.sh
@@ -93,7 +94,7 @@ noinst_SCRIPTS = \
test_data=
-# TODO: Delete the test-*.d directories when cleaning up. Yeah!
+# TODO: Delete the test-*.d directories when cleaning up.
CLEANFILES = tmp-test-*.d/* tmp-try-*.d/*
# Autogenerated by a script
@@ -113,10 +114,13 @@ LDADD = libhsync.la $(LIBOBJS)
# end users wanting to run them. So for the time being they are not
# installed.
-bin_PROGRAMS = rdiff
+# bin_PROGRAMS = rsum
+# rdiff
-rdiff_SOURCES = rdiff.c \
- isprefix.c isprefix.h
+# rsum_SOURCES = rsum.c
+
+# rdiff_SOURCES = rdiff.c \
+# isprefix.c isprefix.h
check_PROGRAMS = isprefix.driver
diff --git a/TODO b/TODO
index 5fb003c..69c8474 100644
--- a/TODO
+++ b/TODO
@@ -177,7 +177,8 @@ $Id$
sufficient.
* SCO and similar things on 32-bit platforms may be more
- difficult.
+ difficult. Some SCO systems have no 64-bit types at all, so
+ there we will have to do without.
* On larger Unix platforms we hope that large file support will
be the default.
diff --git a/acconfig.h b/acconfig.h
index 8f1ad83..f490292 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -20,7 +20,7 @@
#undef _LARGEFILE_SOURCE
#undef _LARGEFILE64_SOURCE
-/* How many bits in an off_t? */
+/* How many bits would you like to have in an off_t? */
#undef _FILE_OFFSET_BITS
/* Define to include GNU C library extensions. */
diff --git a/autogen.sh b/autogen.sh
index d9ce4ef..428d522 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -34,6 +34,12 @@ FILE=hsync.h
DIE=0
+cache="$srcdir/config.cache"
+[ -f "$cache" ] && {
+ echo "Deleting $cache"
+ rm "$cache"
+}
+
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $PROJECT."
diff --git a/base64.c b/base64.c
index 2094166..54b3fa2 100644
--- a/base64.c
+++ b/base64.c
@@ -20,7 +20,7 @@
*/
-#include "config.h"
+#include <config.h>
#include <string.h>
#include <stdio.h>
diff --git a/buf.c b/buf.c
new file mode 100644
index 0000000..b0d72c3
--- /dev/null
+++ b/buf.c
@@ -0,0 +1,176 @@
+/*= -*- c-file-style: "linux" -*-
+ *
+ * libhsync -- the library for network deltas
+ * $Id$
+ *
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+ /*
+ * Pick a window, Jimmy, you're leaving.
+ * -- Martin Schwenke, regularly
+ */
+
+
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include "hsync.h"
+#include "hsyncfile.h"
+#include "trace.h"
+#include "buf.h"
+#include "util.h"
+
+
+int hs_inbuflen = 1000, hs_outbuflen = 1000;
+
+
+struct hs_filebuf {
+ FILE *f;
+ hs_stream_t *stream;
+ char *buf;
+ size_t buf_len;
+};
+
+
+
+hs_filebuf_t *hs_filebuf_new(FILE *f, hs_stream_t *stream, size_t buf_len)
+{
+ hs_filebuf_t *pf = hs_alloc_struct(hs_filebuf_t);
+
+ pf->buf = hs_alloc(buf_len, "file buffer");
+ pf->buf_len = buf_len;
+ pf->f = f;
+ pf->stream = stream;
+
+ return pf;
+}
+
+
+void hs_filebuf_free(hs_filebuf_t *fb)
+{
+ hs_bzero(fb, sizeof *fb);
+ free(fb);
+}
+
+
+/*
+ * If the stream has no more data available, read some from F into BUF,
+ * and let the stream use that.
+ */
+hs_result hs_infilebuf_fill(hs_filebuf_t *fb)
+{
+ hs_stream_t * const stream = fb->stream;
+ FILE *f = fb->f;
+
+ /* This is only allowed if either the stream has no input buffer
+ * yet, or that buffer could possibly be BUF. */
+ if (stream->next_in != NULL) {
+ assert(stream->avail_in <= fb->buf_len);
+ assert(stream->next_in >= fb->buf);
+ assert(stream->next_in <= fb->buf + fb->buf_len);
+ } else {
+ assert(stream->avail_in == 0);
+ }
+
+ if (stream->avail_in == 0 && !feof(fb->f)) {
+ int len = fread(fb->buf, 1, fb->buf_len, f);
+ if (len < 0) {
+ hs_error("error filling stream from file: %s",
+ strerror(errno));
+ return HS_IO_ERROR;
+ }
+ stream->avail_in = len;
+ stream->next_in = fb->buf;
+ }
+
+ return HS_OK;
+}
+
+
+/*
+ * The stream is already using BUF for an output buffer, and probably
+ * contains some buffered output now. Write this out to F, and reset
+ * the buffer cursor.
+ */
+hs_result hs_outfilebuf_drain(hs_filebuf_t *fb)
+{
+ int present;
+ hs_stream_t * const stream = fb->stream;
+ FILE *f = fb->f;
+
+ /* This is only allowed if either the stream has no output buffer
+ * yet, or that buffer could possibly be BUF. */
+ if (stream->next_out == NULL) {
+ assert(stream->avail_out == 0);
+
+ stream->next_out = fb->buf;
+ stream->avail_out = fb->buf_len;
+
+ return HS_OK;
+ }
+
+ assert(stream->avail_out <= fb->buf_len);
+ assert(stream->next_out >= fb->buf);
+ assert(stream->next_out <= fb->buf + fb->buf_len);
+
+ present = stream->next_out - fb->buf;
+ if (present > 0) {
+ int result;
+
+ assert(present > 0);
+
+ result = fwrite(fb->buf, 1, present, f);
+ if (present != result) {
+ hs_error("error draining stream to file: %s",
+ strerror(errno));
+ return HS_IO_ERROR;
+ }
+
+ stream->next_out = fb->buf;
+ stream->avail_out = fb->buf_len;
+ }
+
+ return HS_OK;
+}
+
+
+/*
+ * Default copy implementation that retrieves a part of a stdio file.
+ */
+hs_result hs_file_copy_cb(void *arg, size_t *len, void **buf)
+{
+ int got;
+
+ got = fread(*buf, 1, *len, (FILE *) arg);
+ if (got == -1) {
+ hs_error(strerror(errno));
+ return HS_IO_ERROR;
+ } else if (got == 0) {
+ hs_error("unexpected eof");
+ return HS_SHORT_STREAM;
+ } else {
+ *len = got;
+ return HS_OK;
+ }
+}
diff --git a/buf.h b/buf.h
new file mode 100644
index 0000000..273bd9d
--- /dev/null
+++ b/buf.h
@@ -0,0 +1,31 @@
+/*= -*- c-file-style: "linux" -*-
+ *
+ * libhsync -- the library for network deltas
+ * $Id$
+ *
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+typedef struct hs_filebuf hs_filebuf_t;
+
+hs_filebuf_t *hs_filebuf_new(FILE *f, hs_stream_t *stream, size_t buf_len);
+
+void hs_filebuf_free(hs_filebuf_t *fb);
+
+hs_result hs_infilebuf_fill(hs_filebuf_t *fb);
+
+hs_result hs_outfilebuf_drain(hs_filebuf_t *);
diff --git a/checksum.c b/checksum.c
index 6e8e6e4..bfb3d79 100644
--- a/checksum.c
+++ b/checksum.c
@@ -2,7 +2,7 @@
*
* $Id$
*
- * Copyright (C) 1999, 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 1999, 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
* Copyright (C) 1996 by Andrew Tridgell
* Copyright (C) 1996 by Paul Mackerras
*
@@ -21,7 +21,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
+#include <config.h>
#include <assert.h>
#include <stdlib.h>
@@ -45,7 +45,7 @@ int checksum_seed = 0;
* A simple 32 bit checksum that can be updated from either end
* (inspired by Mark Adler's Adler-32 checksum)
*/
-uint32_t _hs_calc_weak_sum(void const *p, int len)
+uint32_t hs_calc_weak_sum(void const *p, int len)
{
int i;
uint32_t s1, s2;
@@ -79,7 +79,7 @@ uint32_t _hs_calc_weak_sum(void const *p, int len)
* Since we can't retry a web transaction I'm not sure if it's very
* useful in rproxy.
*/
-void _hs_calc_strong_sum(void const *buf,
+void hs_calc_strong_sum(void const *buf,
size_t len,
uint8_t *sum,
size_t sum_len)
@@ -93,3 +93,6 @@ void _hs_calc_strong_sum(void const *buf,
memcpy(sum, tsum, sum_len);
}
+
+
+
diff --git a/checksum.h b/checksum.h
index 0b9ecca..f9469f0 100644
--- a/checksum.h
+++ b/checksum.h
@@ -19,7 +19,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-uint32_t _hs_calc_weak_sum(void const *buf1, int len);
+uint32_t hs_calc_weak_sum(void const *buf1, int len);
-void _hs_calc_strong_sum(void const *buf, size_t buf_len,
+void hs_calc_strong_sum(void const *buf, size_t buf_len,
uint8_t *sum, size_t sum_len);
diff --git a/codeheader.c b/codeheader.c
index dab3ce6..ce05487 100644
--- a/codeheader.c
+++ b/codeheader.c
@@ -3,7 +3,7 @@
* libhsync -- the library for network deltas
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
diff --git a/command.c b/command.c
index c7b69c1..edce7f1 100644
--- a/command.c
+++ b/command.c
@@ -21,7 +21,7 @@
*/
-#include "config.h"
+#include <config.h>
#include <assert.h>
#include <stdlib.h>
@@ -31,7 +31,7 @@
#include "command.h"
/* For debugging purposes, here are some human-readable forms. */
-struct hs_op_kind_name const _hs_op_kind_names[] = {
+struct hs_op_kind_name const hs_op_kind_names[] = {
{"EOF", HS_KIND_EOF },
{"COPY", HS_KIND_COPY },
{"LITERAL", HS_KIND_LITERAL },
@@ -45,11 +45,11 @@ struct hs_op_kind_name const _hs_op_kind_names[] = {
/*
* Return a human-readable name for KIND.
*/
-char const * _hs_op_kind_name(enum hs_op_kind kind)
+char const * hs_op_kind_name(enum hs_op_kind kind)
{
const struct hs_op_kind_name *k;
- for (k = _hs_op_kind_names; k->kind; k++) {
+ for (k = hs_op_kind_names; k->kind; k++) {
if (k->kind == kind) {
return k->name;
}
diff --git a/command.h b/command.h
index c57c02d..dee6bff 100644
--- a/command.h
+++ b/command.h
@@ -53,6 +53,6 @@ typedef struct hs_op_kind_name {
enum hs_op_kind const kind;
} hs_op_kind_name_t;
-char const * _hs_op_kind_name(enum hs_op_kind);
+char const * hs_op_kind_name(enum hs_op_kind);
diff --git a/config.h b/config.h
index bfa0cdd..8403639 100644
--- a/config.h
+++ b/config.h
@@ -1,9 +1,18 @@
/* config.h. Generated automatically by configure. */
/* config.h.in. Generated automatically from configure.in by autoheader. */
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+/* #undef off_t */
+
/* Define if you need to in order for stat and other things to work. */
/* #undef _POSIX_SOURCE */
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+/* #undef size_t */
+
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
@@ -16,6 +25,9 @@
/* Define this if your sockaddr structure contains sin_len */
/* #undef HAVE_SOCK_SIN_LEN */
+/* How many bits would you like to have in an off_t? */
+#define _FILE_OFFSET_BITS 64
+
/* Define to include GNU C library extensions. */
#define _GNU_SOURCE 1
@@ -25,9 +37,6 @@
/* Canonical GNU hostname */
#define HS_CANONICAL_HOST "i686-pc-linux-gnu"
-/* The number of bytes in a off_t. */
-#define SIZEOF_OFF_T 4
-
/* The number of bytes in a unsigned char. */
#define SIZEOF_UNSIGNED_CHAR 1
diff --git a/configure.in b/configure.in
index f88c0be..3fda1a3 100644
--- a/configure.in
+++ b/configure.in
@@ -1,8 +1,11 @@
-# -*- shell-script -*-
dnl Process this file with autoconf to produce a configure script.
-
AC_REVISION($Id$)
+# -*- shell-script -*-
+
+# Copyright (C) 1999, 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
+
AC_INIT(trace.c)
+
my_version=0.6.0dev
my_package=libhsync
my_url=http://linuxcare.com.au/rproxy/
@@ -14,10 +17,8 @@ AM_PROG_LIBTOOL
AM_CONFIG_HEADER(config.h)
-dnl Set up to get as many features as we can manage
-dnl trying to do large file support is not so simple
-dnl we will turn it off for the moment
-dnl AC_DEFINE(_FILE_OFFSET_BITS, 64)
+# Set up to get as many features as we can manage
+AC_DEFINE(_FILE_OFFSET_BITS, 64)
AC_DEFINE(_GNU_SOURCE)
AC_CANONICAL_HOST
@@ -29,6 +30,11 @@ AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_RANLIB
+AC_TYPE_SIZE_T
+AC_TYPE_OFF_T
+
+AC_C_CONST
+
# See if the compiler has the nice GNU feature of
# putting argv[0] into a global
AC_MSG_CHECKING([for program_invocation_short_name])
@@ -94,8 +100,6 @@ then
AC_MSG_WARN(unsigned char seems to be $ac_cv_sizeof_unsigned_char bytes. Expect trouble.)
fi
-AC_CHECK_SIZEOF(off_t, 4)
-
dnl Checks for header files.
AC_CHECK_HEADERS(sys/endian.h)
AC_HEADER_STDC
diff --git a/copyq.c b/copyq.c
index ce34bae..91ba29f 100644
--- a/copyq.c
+++ b/copyq.c
@@ -27,8 +27,8 @@
/* If possible, append this copy command to the end of the previous
* one. If not, flush the existing command and begin a new one. */
int
-_hs_queue_copy(hs_write_fn_t write_fn, void *write_priv,
- _hs_copyq_t * copyq,
+hs_queue_copy(hs_write_fn_t write_fn, void *write_priv,
+ hs_copyq_t * copyq,
off_t start, size_t len, hs_stats_t * stats)
{
int ret;
@@ -45,7 +45,7 @@ _hs_queue_copy(hs_write_fn_t write_fn, void *write_priv,
} else {
/* Of course, COPY commands don't *have* to follow each other. If we
get two non-contiguous ones, then we flush and start again. */
- ret = _hs_copyq_push(write_fn, write_priv, copyq, stats);
+ ret = hs_copyq_push(write_fn, write_priv, copyq, stats);
copyq->start = start;
copyq->len = len;
return ret;
@@ -58,8 +58,8 @@ _hs_queue_copy(hs_write_fn_t write_fn, void *write_priv,
* them out.
*/
int
-_hs_copyq_push(hs_write_fn_t write_fn, void *write_priv,
- _hs_copyq_t * copyq, hs_stats_t * stats)
+hs_copyq_push(hs_write_fn_t write_fn, void *write_priv,
+ hs_copyq_t * copyq, hs_stats_t * stats)
{
int ret;
@@ -67,7 +67,7 @@ _hs_copyq_push(hs_write_fn_t write_fn, void *write_priv,
return 0;
assert(copyq->len > 0);
- ret = _hs_emit_copy(write_fn, write_priv,
+ ret = hs_emit_copy(write_fn, write_priv,
copyq->start, copyq->len, stats);
copyq->len = 0;
diff --git a/delta.c b/delta.c
index deb6ec5..da2399e 100644
--- a/delta.c
+++ b/delta.c
@@ -3,7 +3,7 @@
* libhsync -- library for network deltas
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -34,26 +34,17 @@
/*
* Eventually, the delta algorithm has to maintain one block of
- * readahead or readbehind to check the strong checksum. Normally we
- * don't have to actually do anything with this data, just keep it.
- *
- * Probably a reasonable way to implement this is with a double-long
- * buffer and data scrolling through that. When a weak match is found,
- * we check the strong checksum against the readbehind buffer.
+ * readahead or readbehind to check the strong checksum.
*
* On each entry to the iterator, we first need to try to flush any
* outstanding output from either the tube or a copy instruction.
*/
-#include "config.h"
+#include <config.h>
#include <assert.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
#include <sys/types.h>
#include <limits.h>
#include <inttypes.h>
@@ -64,68 +55,46 @@
#include "emit.h"
#include "stream.h"
#include "util.h"
+#include "job.h"
-enum hs_delta_state {
- hs_s_header,
- hs_body
-};
-
-struct hs_delta_job {
- hs_stream_t *stream;
-};
-
-
-/*
- * Prepare to compute a delta on a stream.
- */
-hs_delta_job_t *hs_delta_begin(hs_stream_t *stream)
+static hs_result hs_delta_s_fake(hs_job_t *job)
{
- hs_delta_job_t *job;
+ hs_stream_t * const stream = job->stream;
+ size_t avail = stream->avail_in;
+
+ hs_emit_literal_cmd(stream, avail);
+ hs_blow_copy(stream, avail);
- job = _hs_alloc_struct(hs_delta_job_t);
- job->stream = stream;
-
- _hs_emit_delta_header(stream);
-
- return job;
+ if (hs_stream_is_empty(stream))
+ return HS_OK;
+ else
+ return HS_BLOCKED;
}
-/*
- * Consume and produce data to generate a delta.
- */
-int hs_delta_iter(hs_delta_job_t *job, int ending)
+static hs_result hs_delta_s_header(hs_job_t *job)
{
- int avail;
- hs_stream_t * const stream = job->stream;
-
- /* Find out how much input is available. Write it out as one big
- * command, and remove it from the input stream. */
- if (!_hs_tube_catchup(stream))
- return HS_OK;
+ hs_emit_delta_header(job->stream);
- avail = stream->avail_in;
- _hs_emit_literal_cmd(stream, avail);
- _hs_blow_copy(stream, avail);
+ job->statefn = hs_delta_s_fake;
- if (_hs_stream_is_empty(stream))
- return HS_OK;
- else
- return HS_BLOCKED;
+ return HS_OK;
}
-
/*
- * Close of processing of a delta. This doesn't terminate the stream,
- * it just frees up any memory that was allocated.
+ * Prepare to compute a delta on a stream.
*/
-int hs_delta_finish(hs_delta_job_t *job)
+hs_job_t *hs_delta_begin(hs_stream_t *stream)
{
- _hs_bzero(job, sizeof *job);
+ hs_job_t *job;
- free(job);
+ job = hs_job_new(stream);
- return HS_OK;
+ job->statefn = hs_delta_s_header;
+
+ return job;
}
+
+
diff --git a/emit.c b/emit.c
index 426cd47..df17d51 100644
--- a/emit.c
+++ b/emit.c
@@ -28,7 +28,7 @@
*/
-#include "config.h"
+#include <config.h>
#include <assert.h>
@@ -55,19 +55,19 @@
* Write the magic for the start of a delta.
*/
void
-_hs_emit_delta_header(hs_stream_t *stream)
+hs_emit_delta_header(hs_stream_t *stream)
{
- _hs_trace("emit DELTA");
- _hs_squirt_n32(stream, HS_DELTA_MAGIC);
+ hs_trace("emit DELTA");
+ hs_squirt_n32(stream, HS_DELTA_MAGIC);
}
/* Write a LITERAL command. */
void
-_hs_emit_literal_cmd(hs_stream_t *stream, int len)
+hs_emit_literal_cmd(hs_stream_t *stream, int len)
{
- _hs_trace("emit LITERAL(%d)", len);
- _hs_squirt_n8(stream, HS_OP_LITERAL_N32);
- _hs_squirt_n32(stream, len);
+ hs_trace("emit LITERAL(%d)", len);
+ hs_squirt_n8(stream, HS_OP_LITERAL_N32);
+ hs_squirt_n32(stream, len);
}
diff --git a/emit.h b/emit.h
index 6f489e8..9b0abbe 100644
--- a/emit.h
+++ b/emit.h
@@ -26,5 +26,5 @@
*/
-void _hs_emit_delta_header(hs_stream_t *stream);
-void _hs_emit_literal_cmd(hs_stream_t *stream, int len);
+void hs_emit_delta_header(hs_stream_t *stream);
+void hs_emit_literal_cmd(hs_stream_t *stream, int len);
diff --git a/file.c b/file.c
deleted file mode 100644
index 78c17d9..0000000
--- a/file.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*= -*- c-file-style: "linux" -*-
- *
- * libhsync -- dynamic caching and delta update in HTTP
- * $Id$
- *
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * file.c -- This looks after the high-level, stdio-flavoured
- * interface.
- */
-
-
- /*
- * "You know, it'd be much cheaper if
- * you flew on the 25th of December."
- */
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <limits.h>
-#include <errno.h>
-#include <string.h>
-
-#include "hsync.h"
-#include "util.h"
-#include "stream.h"
-#include "trace.h"
-#include "streamfile.h"
-#include "sumset.h"
-#include "hsyncfile.h"
-
-
-int hs_inbuflen = 500, hs_outbuflen = 600;
-
-static const int HS_PATCH_FILE_TAG = 201214,
- HS_MKSUM_FILE_TAG = 201215;
-
-typedef struct hs_file {
- int tag;
- FILE *basis_file, *in_file, *out_file;
-
- char *buf;
- size_t buf_len;
-
- hs_stream_t *stream;
-
- /* one of the following: */
- hs_patch_job_t *patch_job;
- hs_mksum_job_t *mksum_job;
-} hs_file_t;
-
-
-/*
- * Extract from a void pointer, and check the dogtag.
- */
-static hs_file_t *_hs_file_check(void *p, int tag) {
- hs_file_t *pf = (hs_file_t *) p;
- assert(pf->tag == tag);
- return pf;
-}
-
-
-static hs_file_t *_hs_file_new(size_t buf_len) {
- hs_file_t *pf = _hs_alloc_struct(hs_file_t);
- pf->stream = _hs_alloc_struct(hs_stream_t);
- hs_stream_init(pf->stream);
-
- pf->buf = _hs_alloc(buf_len, "file buffer");
- pf->buf_len = buf_len;
-
- return pf;
-}
-
-
-/*
- * Open a new hsync file which will apply a patch. As you read from
- * the file using hs_read(), you'll receive parts of the new file.
- */
-HSFILE *hs_patch_open(FILE *basis_file, FILE *delta_file)
-{
- hs_file_t *pf;
-
- pf = _hs_file_new(hs_inbuflen);
-
- pf->tag = HS_PATCH_FILE_TAG;
- pf->basis_file = basis_file;
- pf->in_file = delta_file;
-
- pf->patch_job = hs_patch_begin(pf->stream, hs_file_copy_cb, basis_file);
-
- return pf;
-}
-
-
-
-/*
- * Open a file to write out the signature of caller-supplied data.
- */
-HSFILE *hs_mksum_open(FILE *sig_file, int block_len, int strong_sum_len)
-{
- hs_file_t *pf = _hs_file_new(hs_outbuflen);
-
- pf->tag = HS_MKSUM_FILE_TAG;
- pf->out_file = sig_file;
- pf->mksum_job = hs_mksum_begin(pf->stream, block_len, strong_sum_len);
-
- return pf;
-}
-
-
-
-/*
- * Read up to *LEN bytes from PF. At end of file, return HS_OK; if
- * the patch is not yet complete returns HS_BLOCKED; if an error
- * occurred returns an appropriate code. Adjusts LEN to show how much
- * was actually read.
- */
-enum hs_result hs_patch_read(HSFILE *f, void *buf, size_t *len)
-{
- hs_file_t *pf = _hs_file_check(f, HS_PATCH_FILE_TAG);
- enum hs_result result;
-
- pf->stream->next_out = buf;
- pf->stream->avail_out = *len;
-
- do {
- _hs_fill_from_file(pf->stream, pf->buf, pf->buf_len,
- pf->in_file);
-
- result = hs_patch_iter(pf->patch_job);
-
- if (result == HS_BLOCKED && feof(pf->in_file) &&
- !pf->stream->avail_in) {
- /* The library wants more input, but it has
- * none in its internal buffer and we're at
- * the end of the file. Therefore the delta
- * must have been truncated. */
- result = HS_SHORT_STREAM;
- }
- } while (result == HS_BLOCKED);
-
- /* Return the amount of output actually available. */
- assert(pf->stream->next_out >= (char *) buf);
- *len = pf->stream->next_out - (char *) buf;
- _hs_trace("returns %d bytes: %s", *len, hs_strerror(result));
-
- return result;
-}
-
-
-
-enum hs_result hs_mksum_write(HSFILE *f, void *buf, size_t len)
-{
- hs_file_t *pf = _hs_file_check(f, HS_MKSUM_FILE_TAG);
- enum hs_result result, io_result;
-
- pf->stream->next_in = buf;
- pf->stream->avail_in = len;
-
- do {
- result = hs_mksum_iter(pf->mksum_job, 0);
-
- io_result = _hs_drain_to_file(pf->stream, pf->buf, pf->buf_len,
- pf->out_file);
-
- if (io_result != HS_OK)
- return result;
- } while (result == HS_BLOCKED && pf->stream->avail_in > 0);
-
- _hs_trace("returns %s(%d)", hs_strerror(result), result);
-
- return result;
-}
-
-
-/*
- * Close off a patch file. If the patch has not finished, then the
- * rest of the data is just lost. The files used are not closed.
- */
-enum hs_result hs_patch_close(HSFILE *f)
-{
- hs_file_t *pf = _hs_file_check(f, HS_PATCH_FILE_TAG);
- if (pf->buf)
- free(pf->buf);
- hs_patch_finish(pf->patch_job);
- return HS_OK;
-}
-
-
-
-enum hs_result hs_mksum_close(HSFILE *f)
-{
- hs_file_t *pf = _hs_file_check(f, HS_MKSUM_FILE_TAG);
- enum hs_result result, io_result;
-
- pf->stream->next_in = 0;
- pf->stream->avail_in = 0;
-
- /* Continue to run until all stream data has drained; then
- * deallocate and leave. */
- do {
- result = hs_mksum_iter(pf->mksum_job, 1);
-
- io_result = _hs_drain_to_file(pf->stream, pf->buf, pf->buf_len,
- pf->out_file);
-
- if (io_result != HS_OK)
- return result;
- } while (result == HS_BLOCKED);
-
- if (pf->buf)
- free(pf->buf);
- hs_mksum_finish(pf->mksum_job);
- return HS_OK;
-}
-
-
-
-/*
- * Default copy implementation that retrieves a part of a stdio file.
- */
-enum hs_result hs_file_copy_cb(void *arg, size_t *len, void **buf)
-{
- int got;
-
- got = fread(*buf, 1, *len, (FILE *) arg);
- if (got == -1) {
- _hs_error(strerror(errno));
- return HS_IO_ERROR;
- } else if (got == 0) {
- _hs_error("unexpected eof");
- return HS_SHORT_STREAM;
- } else {
- *len = got;
- return HS_OK;
- }
-}
diff --git a/file.h b/file.h
deleted file mode 100644
index 0fee777..0000000
--- a/file.h
+++ /dev/null
@@ -1 +0,0 @@
-#error unused
diff --git a/fileutil.c b/fileutil.c
index 93d6253..ec8d4e3 100644
--- a/fileutil.c
+++ b/fileutil.c
@@ -21,7 +21,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
+#include <config.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
@@ -42,13 +42,13 @@
void
-_hs_file_close(int fd)
+hs_file_close(int fd)
{
if (fd == -1)
- _hs_error("warning: close called with fd of -1");
+ hs_error("warning: close called with fd of -1");
if (close(fd) == -1) {
- _hs_error("error closing fd %d: %s",
+ hs_error("error closing fd %d: %s",
fd, strerror(errno));
}
}
@@ -58,7 +58,7 @@ _hs_file_close(int fd)
* Open a file, with special handling for `-' on input and output.
*/
FILE *
-_hs_file_open(char const *filename, int mode)
+hs_file_open(char const *filename, int mode)
{
int fd;
FILE *f;
@@ -80,7 +80,7 @@ _hs_file_open(char const *filename, int mode)
fd = open(filename, mode, 0666);
if (fd == -1) {
- _hs_error("Error opening \"%s\" for %s: %s", filename,
+ hs_error("Error opening \"%s\" for %s: %s", filename,
(mode & O_WRONLY) ? "write" : "read",
strerror(errno));
exit(1);
@@ -88,7 +88,7 @@ _hs_file_open(char const *filename, int mode)
f = fdopen(fd, is_write ? "w" : "r");
if (!f) {
- _hs_error("Error opening stream on fd%d: %s", fd,
+ hs_error("Error opening stream on fd%d: %s", fd,
strerror(errno));
exit(1);
}
diff --git a/fileutil.h b/fileutil.h
index 67bcf43..a49b413 100644
--- a/fileutil.h
+++ b/fileutil.h
@@ -20,7 +20,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-int _hs_file_copy_all(int from_fd, int to_fd);
+int hs_file_copy_all(int from_fd, int to_fd);
-FILE * _hs_file_open(char const *filename, int mode);
-void _hs_file_close(int fd);
+FILE * hs_file_open(char const *filename, int mode);
+void hs_file_close(int fd);
diff --git a/hex.c b/hex.c
index 209dbd5..841185e 100644
--- a/hex.c
+++ b/hex.c
@@ -2,7 +2,7 @@
* rproxy -- dynamic caching and delta update in HTTP
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -19,7 +19,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
+#include <config.h>
#include <assert.h>
diff --git a/hsync.h b/hsync.h
index 3f280a6..0139e74 100644
--- a/hsync.h
+++ b/hsync.h
@@ -3,7 +3,7 @@
* libhsync -- library for network deltas
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -20,28 +20,20 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
-/*
- * hsync.h: public interface to libhsync.
- */
-
-extern char const *const hs_libhsync_version;
-extern int const hs_libhsync_file_offset_bits;
+ /*
+ * You should never wear your best
+ * trousers when you go out to fight for
+ * freedom and liberty.
+ * -- Henrik Ibsen
+ */
-void hs_show_version(FILE *out, char const *program);
-void hs_show_licence(FILE *out);
-
/*
- * For the moment, we always work in the C library's off_t.
- *
- * Supporting large files on 32-bit Linux is *NOT* just a matter of
- * setting these: people will typically need a different libc and
- * possibly an LFS-supported kernel too. :-(
- *
- * Anyhow, will anyone really have single HTTP requests >=2GB?
+ * hsync.h: public interface to libhsync.
*/
+extern char const hs_libhsync_version[];
+extern char const hs_licence_string[];
/***********************************************************************
@@ -79,15 +71,15 @@ void hs_base64(unsigned char const *buf, int n, char *out);
/* Return codes */
-enum hs_result {
+typedef enum hs_result {
HS_OK = 0, /* completed successfully */
HS_BLOCKED = 1, /* OK, but more remains to be done */
- HS_RUN_OK = 2, /* not finished or blocked */
+ HS_RUN_OK = 2, /* not yet finished or blocked */
HS_IO_ERROR = (-1), /* error in file or network IO */
HS_MEM_ERROR = (-2), /* out of memory */
HS_SHORT_STREAM = (-3), /* unexpected eof */
HS_BAD_MAGIC = (-4) /* illegal value on stream */
-};
+} hs_result;
/***********************************************************************
@@ -127,7 +119,15 @@ void hs_mdfour_result(hs_mdfour_t * md, unsigned char *out);
char *hs_format_stats(hs_stats_t const *, char *, size_t);
int hs_log_stats(hs_stats_t const *stats);
-char const *hs_strerror(enum hs_result r);
+char const *hs_strerror(hs_result r);
+
+
+
+typedef struct hs_sumset hs_sumset_t;
+
+void hs_free_sumset(hs_sumset_t *);
+void hs_sumset_dump(hs_sumset_t const *);
+
/***********************************************************************
* All encoding routines follow a calling protocol similar to that of
@@ -163,25 +163,22 @@ void hs_stream_init(hs_stream_t *);
#define HS_DEFAULT_BLOCK_LEN 2048
-typedef struct hs_mksum_job hs_mksum_job_t;
-hs_mksum_job_t *hs_mksum_begin(hs_stream_t *stream,
- size_t new_block_len, size_t strong_sum_len);
-int hs_mksum_iter(hs_mksum_job_t * job, int ending);
-int hs_mksum_finish(hs_mksum_job_t * job);
+typedef struct hs_job hs_job_t;
-typedef struct hs_delta_job hs_delta_job_t;
-hs_delta_job_t *hs_delta_begin(hs_stream_t *stream);
-int hs_delta_iter(hs_delta_job_t *, int ending);
-int hs_delta_finish(hs_delta_job_t *);
+hs_job_t *hs_accum_begin(hs_stream_t *);
+hs_result hs_job_iter(hs_job_t *, int ending);
+hs_result hs_job_free(hs_job_t *);
-/* Callback used to retrieve parts of the basis file. */
-typedef enum hs_result (hs_copy_cb)(void *opaque, size_t *len, void **result);
+int hs_accum_value(hs_job_t *, char *sum, size_t sum_len);
+
+hs_job_t *hs_mksum_begin(hs_stream_t *stream,
+ size_t new_block_len, size_t strong_sum_len);
-typedef struct hs_patch_job hs_patch_job_t;
-hs_patch_job_t *hs_patch_begin(hs_stream_t *stream, hs_copy_cb *, void *copy_arg);
-int hs_patch_iter(hs_patch_job_t *);
-int hs_patch_finish(hs_patch_job_t *);
+hs_job_t *hs_delta_begin(hs_stream_t *stream);
+/* Callback used to retrieve parts of the basis file. */
+typedef hs_result (hs_copy_cb)(void *opaque, size_t *len, void **result);
+hs_job_t *hs_patch_begin(hs_stream_t *, hs_copy_cb *, void *copy_arg);
diff --git a/hsyncfile.h b/hsyncfile.h
index 0e03c05..acff985 100644
--- a/hsyncfile.h
+++ b/hsyncfile.h
@@ -3,7 +3,7 @@
* libhsync -- the library for network deltas
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -76,4 +76,6 @@ void hs_mdfour_file(FILE *in_file, char *result);
enum hs_result hs_rdiff_signature(int argc, char *argv[]);
enum hs_result hs_rdiff_delta(int argc, char *argv[]);
enum hs_result hs_rdiff_patch(int argc, char *argv[]);
-enum hs_result hs_rdiff_md4(int argc, char *argv[]);
+enum hs_result hs_rdiff_sum(int argc, char *argv[]);
+
+hs_result hs_whole_signature(FILE *old_file, FILE *sig_file, size_t, size_t);
diff --git a/job.c b/job.c
new file mode 100644
index 0000000..ab1dce5
--- /dev/null
+++ b/job.c
@@ -0,0 +1,95 @@
+/*= -*- c-file-style: "linux" -*-
+ *
+ * libhsync -- the library for network deltas
+ * $Id$
+ *
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+ /*
+ * The hard, lifeless I covered up the
+ * warm, pulsing It; protecting and
+ * sheltering.
+ */
+
+
+/*
+ * Generic state-machine "job" mechanism.
+ */
+
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "hsync.h"
+#include "stream.h"
+#include "util.h"
+#include "job.h"
+#include "trace.h"
+
+
+hs_job_t * hs_job_new(hs_stream_t *stream)
+{
+ hs_job_t *job;
+
+ job = hs_alloc_struct(hs_job_t);
+
+ hs_stream_check(stream);
+ job->stream = stream;
+
+ return job;
+}
+
+
+hs_result hs_job_free(hs_job_t *job)
+{
+ hs_bzero(job, sizeof *job);
+ free(job);
+
+ return HS_OK;
+}
+
+
+
+/*
+ * Nonblocking iteration interface for making up a file sum.
+ *
+ * ENDING should be true if there is no more data after what's in the
+ * input buffer. The final block checksum will run across whatever's
+ * in there, without trying to accumulate anything else.
+ */
+hs_result hs_job_iter(hs_job_t *job, int ending)
+{
+ enum hs_result result;
+
+ if (ending)
+ job->near_end = 1;
+
+ while (1) {
+ result = hs_tube_catchup(job->stream);
+ if (result != HS_OK)
+ return result;
+
+ result = job->statefn(job);
+ if (result != HS_RUN_OK)
+ return result;
+ }
+}
+
diff --git a/job.h b/job.h
new file mode 100644
index 0000000..2dc4fde
--- /dev/null
+++ b/job.h
@@ -0,0 +1,49 @@
+/*= -*- c-file-style: "linux" -*-
+ *
+ * libhsync -- the library for network deltas
+ * $Id$
+ *
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/* Generic 'job' state machine. */
+
+struct hs_job {
+ hs_stream_t *stream;
+
+ /* Callback for each processing step. */
+ enum hs_result (*statefn)(hs_job_t *);
+
+ /* Generic storage fields. */
+ size_t block_len;
+ size_t strong_sum_len;
+ int near_end;
+
+ hs_copy_cb *copy_cb;
+ void *copy_arg;
+
+ /* Command byte currently being processed, if any, and lengths
+ * of expected parameters. */
+ int op, param1, param2;
+ struct hs_prototab_ent const *cmd;
+ hs_mdfour_t output_md4;
+};
+
+
+hs_job_t * hs_job_new(hs_stream_t *stream);
+
diff --git a/mdfour.c b/mdfour.c
index 8ee6724..10aa6ae 100644
--- a/mdfour.c
+++ b/mdfour.c
@@ -1,8 +1,9 @@
/* -*- c-file-style: "linux" -*-
- * libhsync -- dynamic caching and delta update in HTTP
+ *
+ * libhsync -- the library for network deltas
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
* Copyright (C) 1997-1999 by Andrew Tridgell
*
* This program is free software; you can redistribute it and/or modify
@@ -21,14 +22,17 @@
*/
/* NOTE: This code makes no attempt to be fast!
-
- It assumes that a int is at least 32 bits long
-
- TODO: Recode to be fast, and to use system integer types. Perhaps if we
- can find an mdfour implementation already on the system (e.g. in OpenSSL)
- then we should use it instead of our own? */
-
-#include "config.h"
+ *
+ * It assumes that a int is at least 32 bits long
+ *
+ * TODO: Recode to be fast, and to use system integer types. Perhaps
+ * if we can find an mdfour implementation already on the system
+ * (e.g. in OpenSSL) then we should use it instead of our own?
+ *
+ * TODO: Apparently rsync 2.4 now has a fast MD4 routine. So we
+ * should copy that into here. */
+
+#include <config.h>
#include <stdlib.h>
diff --git a/mkprototab.sh b/mkprototab.sh
index 4d3f217..c42f7e3 100755
--- a/mkprototab.sh
+++ b/mkprototab.sh
@@ -67,6 +67,8 @@ emit_cmd() {
emit_cmd EOF 0 0 0
+# FIXME: seq(1) may not be available on BSD systems.
+
for i in `seq 1 120`
do
emit_cmd LITERAL $i 0 0
diff --git a/mksum.c b/mksum.c
index 8c52b14..9a29115 100644
--- a/mksum.c
+++ b/mksum.c
@@ -3,7 +3,7 @@
* libhsync -- library for network deltas
* $Id$
*
- * Copyright (C) 1999, 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 1999, 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
* Copyright (C) 1999 by Andrew Tridgell <tridge@samba.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -24,9 +24,14 @@
/*
* mksum: Generate and write out checksums using the stream interface.
+ *
+ * Generating checksums is pretty easy, since we can always just
+ * process whatever data is available. When a whole block has
+ * arrived, or we've reached the end of the file, we write the
+ * checksum out.
*/
-#include "config.h"
+#include <config.h>
#include <stdlib.h>
#include <stdio.h>
@@ -36,51 +41,49 @@
#include "hsync.h"
#include "stream.h"
#include "util.h"
+#include "job.h"
#include "protocol.h"
#include "netint.h"
#include "trace.h"
#include "checksum.h"
-const int HS_MKSUM_TAG = 123124;
-
-struct hs_mksum_job {
- int dogtag;
- hs_stream_t *stream;
- enum hs_result (*statefn)(hs_mksum_job_t *);
- size_t block_len;
- size_t strong_sum_len;
- int near_end;
-};
-
/* Possible state functions for signature generation. */
-static enum hs_result _hs_mksum_s_header(hs_mksum_job_t *);
-static enum hs_result _hs_mksum_s_complete(hs_mksum_job_t *);
-static enum hs_result _hs_mksum_s_generate(hs_mksum_job_t *);
+static enum hs_result hs_mksum_s_header(hs_job_t *);
+static enum hs_result hs_mksum_s_complete(hs_job_t *);
+static enum hs_result hs_mksum_s_generate(hs_job_t *);
/*
* State of trying to send the signature header.
*/
-static enum hs_result _hs_mksum_s_header(hs_mksum_job_t *job)
+static enum hs_result hs_mksum_s_header(hs_job_t *job)
{
- _hs_squirt_n32(job->stream, HS_SIG_MAGIC);
- job->statefn = _hs_mksum_s_generate;
+ hs_squirt_n32(job->stream, HS_SIG_MAGIC);
+ job->statefn = hs_mksum_s_generate;
return HS_RUN_OK;
}
static enum hs_result
-_hs_mksum_do_block(hs_mksum_job_t *job, const void *block, size_t len)
+hs_mksum_do_block(hs_job_t *job, const void *block, size_t len)
{
uint32_t weak_sum;
+ uint8_t strong_sum[HS_MD4_LENGTH];
+ char strong_sum_hex[HS_MD4_LENGTH * 2 + 1];
- weak_sum = _hs_calc_weak_sum(block, len);
- _hs_trace("got weak sum 0x%08x", weak_sum);
+ weak_sum = hs_calc_weak_sum(block, len);
- _hs_squirt_n32(job->stream, weak_sum);
+ hs_calc_strong_sum(block, len, strong_sum, job->strong_sum_len);
+ hs_hexify(strong_sum_hex, strong_sum, job->strong_sum_len);
+
+ hs_squirt_n32(job->stream, weak_sum);
+ hs_blow_literal(job->stream, strong_sum, job->strong_sum_len);
+
+ hs_trace("sent weak sum 0x%08x and strong sum %s", weak_sum,
+ strong_sum_hex);
return HS_RUN_OK;
}
@@ -89,7 +92,7 @@ _hs_mksum_do_block(hs_mksum_job_t *job, const void *block, size_t len)
/*
* State of reading a block and trying to generate its sum.
*/
-static enum hs_result _hs_mksum_s_generate(hs_mksum_job_t *job)
+static enum hs_result hs_mksum_s_generate(hs_job_t *job)
{
enum hs_result result;
int len;
@@ -97,90 +100,48 @@ static enum hs_result _hs_mksum_s_generate(hs_mksum_job_t *job)
/* must get a whole block, otherwise try again */
len = job->block_len;
- result = _hs_scoop_read(job->stream, len, &block);
+ result = hs_scoop_read(job->stream, len, &block);
/* unless we're near eof, in which case we'll accept
* whatever's in there */
if (result == HS_BLOCKED && job->near_end) {
- result = _hs_scoop_read_rest(job->stream, &len, &block);
- job->statefn = _hs_mksum_s_complete;
+ result = hs_scoop_read_rest(job->stream, &len, &block);
+ job->statefn = hs_mksum_s_complete;
} else if (result != HS_OK) {
- _hs_trace("generate stopped: %s", hs_strerror(result));
+ hs_trace("generate stopped: %s", hs_strerror(result));
return result;
}
- _hs_trace("got %d byte block", len);
- fwrite(block, 1, len, stdout);
+ hs_trace("got %d byte block", len);
- return _hs_mksum_do_block(job, block, len);
+ return hs_mksum_do_block(job, block, len);
}
-static enum hs_result _hs_mksum_s_complete(hs_mksum_job_t *UNUSED(job))
+static hs_result hs_mksum_s_complete(hs_job_t *UNUSED(job))
{
- _hs_trace("signature generation has already finished");
+ hs_trace("signature generation has already finished");
return HS_OK;
}
/* Set up a new encoding job. */
-hs_mksum_job_t * hs_mksum_begin(hs_stream_t *stream,
+hs_job_t * hs_mksum_begin(hs_stream_t *stream,
size_t new_block_len, size_t strong_sum_len)
{
- hs_mksum_job_t *job;
+ hs_job_t *job;
- job = _hs_alloc_struct(hs_mksum_job_t);
+ job = hs_job_new(stream);
- _hs_stream_check(stream);
- job->stream = stream;
job->block_len = new_block_len;
- job->dogtag = HS_MKSUM_TAG;
assert(strong_sum_len > 0 && strong_sum_len <= HS_MD4_LENGTH);
job->strong_sum_len = strong_sum_len;
- job->statefn = _hs_mksum_s_header;
+ job->statefn = hs_mksum_s_header;
return job;
}
-
-int hs_mksum_finish(hs_mksum_job_t * job)
-{
- assert(job->dogtag == HS_MKSUM_TAG);
- _hs_bzero(job, sizeof *job);
- free(job);
-
- return HS_OK;
-}
-
-
-
-/*
- * Nonblocking iteration interface for making up a file sum.
- *
- * ENDING should be true if there is no more data after what's in the
- * input buffer. The final block checksum will run across whatever's
- * in there, without trying to accumulate anything else.
- */
-int hs_mksum_iter(hs_mksum_job_t *job, int ending)
-{
- enum hs_result result;
-
- assert(job->dogtag == HS_MKSUM_TAG);
-
- if (ending)
- job->near_end = 1;
-
- while (1) {
- result = _hs_tube_catchup(job->stream);
- if (result != HS_OK)
- return result;
-
- result = job->statefn(job);
- if (result != HS_RUN_OK)
- return result;
- }
-}
diff --git a/mksum.h b/mksum.h
index ab3f5bc..78acf26 100644
--- a/mksum.h
+++ b/mksum.h
@@ -21,6 +21,6 @@
*/
-void _hs_mksum_of_block(byte_t const *p, ssize_t len,
+void hs_mksum_of_block(byte_t const *p, ssize_t len,
hs_write_fn_t write_fn, void *write_priv,
size_t strong_sum_len);
diff --git a/mksum.input/COPYING.sig b/mksum.input/COPYING.sig
index 328b994..eecd62b 100644
--- a/mksum.input/COPYING.sig
+++ b/mksum.input/COPYING.sig
Binary files differ
diff --git a/netint.c b/netint.c
index dc33609..610db8e 100644
--- a/netint.c
+++ b/netint.c
@@ -36,7 +36,7 @@
* is not enough input to proceed.
*/
-#include "config.h"
+#include <config.h>
#include <assert.h>
@@ -64,31 +64,31 @@
#include "stream.h"
-void _hs_squirt_n32(hs_stream_t *stream, int d)
+void hs_squirt_n32(hs_stream_t *stream, int d)
{
uint32_t nd = htonl(d);
- _hs_blow_literal(stream, &nd, sizeof nd);
+ hs_blow_literal(stream, &nd, sizeof nd);
}
void
-_hs_squirt_n8(hs_stream_t *stream, int d)
+hs_squirt_n8(hs_stream_t *stream, int d)
{
uint8_t nd = d;
- _hs_blow_literal(stream, &nd, sizeof nd);
+ hs_blow_literal(stream, &nd, sizeof nd);
}
-enum hs_result _hs_suck_n32(hs_stream_t *stream, int *v)
+enum hs_result hs_suck_n32(hs_stream_t *stream, int *v)
{
void *p;
int result;
- if ((result = _hs_scoop_read(stream, sizeof (uint32_t), &p)))
+ if ((result = hs_scoop_read(stream, sizeof (uint32_t), &p)))
return result;
*v = ntohl(* (uint32_t const *) p);
@@ -97,12 +97,12 @@ enum hs_result _hs_suck_n32(hs_stream_t *stream, int *v)
}
-enum hs_result _hs_suck_n8(hs_stream_t *stream, int *v)
+enum hs_result hs_suck_n8(hs_stream_t *stream, int *v)
{
void *p;
int result;
- if ((result = _hs_scoop_read(stream, sizeof (uint8_t), &p)))
+ if ((result = hs_scoop_read(stream, sizeof (uint8_t), &p)))
return result;
*v = * (uint8_t const *) p;
@@ -112,49 +112,49 @@ enum hs_result _hs_suck_n8(hs_stream_t *stream, int *v)
-enum hs_result _hs_suck_netint(hs_stream_t *stream, int len, int *v)
+enum hs_result hs_suck_netint(hs_stream_t *stream, int len, int *v)
{
switch (len) {
case 1:
- return _hs_suck_n8(stream, v);
+ return hs_suck_n8(stream, v);
case 4:
- return _hs_suck_n32(stream, v);
+ return hs_suck_n32(stream, v);
default:
- _hs_fatal("kaboom! len=%d", len);
+ hs_fatal("kaboom! len=%d", len);
}
}
-int _hs_fits_in_n8(size_t val)
+int hs_fits_in_n8(size_t val)
{
return val <= UINT8_MAX;
}
-int _hs_fits_in_n16(size_t val)
+int hs_fits_in_n16(size_t val)
{
return val <= UINT16_MAX;
}
-int _hs_fits_in_n32(size_t val)
+int hs_fits_in_n32(size_t val)
{
return val <= UINT32_MAX;
}
-int _hs_int_len(off_t val)
+int hs_int_len(off_t val)
{
- if (_hs_fits_in_n8(val))
+ if (hs_fits_in_n8(val))
return 1;
- else if (_hs_fits_in_n16(val))
+ else if (hs_fits_in_n16(val))
return 2;
- else if (_hs_fits_in_n32(val))
+ else if (hs_fits_in_n32(val))
return 4;
else {
- _hs_fatal("can't handle integer this long yet");
+ hs_fatal("can't handle integer this long yet");
}
}
diff --git a/netint.h b/netint.h
index cfa0790..cb08642 100644
--- a/netint.h
+++ b/netint.h
@@ -21,14 +21,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-void _hs_squirt_n32(hs_stream_t *stream, int d);
-void _hs_squirt_n8(hs_stream_t *stream, int d);
+void hs_squirt_n32(hs_stream_t *stream, int d);
+void hs_squirt_n8(hs_stream_t *stream, int d);
-enum hs_result _hs_suck_n32(hs_stream_t *stream, int *v);
-enum hs_result _hs_suck_n8(hs_stream_t *stream, int *v);
-enum hs_result _hs_suck_netint(hs_stream_t *stream, int len, int *v);
+enum hs_result hs_suck_n32(hs_stream_t *stream, int *v);
+enum hs_result hs_suck_n8(hs_stream_t *stream, int *v);
+enum hs_result hs_suck_netint(hs_stream_t *stream, int len, int *v);
-int _hs_fits_in_n8(size_t val);
-int _hs_fits_in_n16(size_t val);
-int _hs_fits_in_n32(size_t val);
-int _hs_int_len(off_t val);
+int hs_fits_in_n8(size_t val);
+int hs_fits_in_n16(size_t val);
+int hs_fits_in_n32(size_t val);
+int hs_int_len(off_t val);
diff --git a/patch.c b/patch.c
index 87bb970..d844719 100644
--- a/patch.c
+++ b/patch.c
@@ -3,7 +3,7 @@
* libhsync -- the library for network deltas
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -22,10 +22,12 @@
/*
- * This is Tranquility.
+ * This is Tranquility Base.
*/
+#include <config.h>
+
/*
* TODO: As output is produced, accumulate the MD4 checksum of the
* output. Then if we find a CHECKSUM command we can check it's
@@ -35,8 +37,6 @@
*/
-#include "config.h"
-
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
@@ -49,50 +49,19 @@
#include "command.h"
#include "prototab.h"
#include "stream.h"
+#include "job.h"
-const int HS_PATCH_TAG = 201210;
-
-
-enum hs_patch_state {
- hs_s_header,
- hs_s_run
-};
-
-
-struct hs_patch_job {
- int dogtag;
- hs_stream_t *stream;
- enum hs_result (*statefn)(hs_patch_job_t *);
-
- hs_copy_cb *copy_cb;
- void *copy_arg;
-
- /* Command byte currently being processed, if any, and lengths
- * of expected parameters. */
- int op, param1, param2;
- hs_prototab_ent_t const *cmd;
-
- /* MD4 checksum of all output data to date. */
- hs_mdfour_t output_md4;
-};
+const int HS_PATCH_TAG = 201210;
/* Local prototypes for state functions. */
-static enum hs_result _hs_patch_s_complete(hs_patch_job_t *);
-static enum hs_result _hs_patch_s_cmdbyte(hs_patch_job_t *);
-static enum hs_result _hs_patch_s_params(hs_patch_job_t *);
-static enum hs_result _hs_patch_s_run(hs_patch_job_t *);
-static enum hs_result _hs_patch_s_literal(hs_patch_job_t *);
-
-
-
-static void _hs_patch_check(const hs_patch_job_t *job)
-{
- assert(job->dogtag == HS_PATCH_TAG);
-}
-
+static enum hs_result hs_patch_s_complete(hs_job_t *);
+static enum hs_result hs_patch_s_cmdbyte(hs_job_t *);
+static enum hs_result hs_patch_s_params(hs_job_t *);
+static enum hs_result hs_patch_s_run(hs_job_t *);
+static enum hs_result hs_patch_s_literal(hs_job_t *);
@@ -101,23 +70,23 @@ static void _hs_patch_check(const hs_patch_job_t *job)
* we've taken that in, we can know how much data to read to get the
* arguments.
*/
-static enum hs_result _hs_patch_s_cmdbyte(hs_patch_job_t *job)
+static enum hs_result hs_patch_s_cmdbyte(hs_job_t *job)
{
enum hs_result result;
- if ((result = _hs_suck_n8(job->stream, &job->op)) != HS_OK)
+ if ((result = hs_suck_n8(job->stream, &job->op)) != HS_OK)
return result;
assert(job->op >= 0 && job->op <= 0xff);
- job->cmd = &_hs_prototab[job->op];
+ job->cmd = &hs_prototab[job->op];
- _hs_trace("got command byte 0x%02x (%s)", job->op,
- _hs_op_kind_name(job->cmd->kind));
+ hs_trace("got command byte 0x%02x (%s)", job->op,
+ hs_op_kind_name(job->cmd->kind));
if (job->cmd->len_1)
- job->statefn = _hs_patch_s_params;
+ job->statefn = hs_patch_s_params;
else
- job->statefn = _hs_patch_s_run;
+ job->statefn = hs_patch_s_run;
return HS_RUN_OK;
}
@@ -127,7 +96,7 @@ static enum hs_result _hs_patch_s_cmdbyte(hs_patch_job_t *job)
* Called after reading a command byte to pull in its parameters and
* then setup to execute the command.
*/
-static enum hs_result _hs_patch_s_params(hs_patch_job_t *job)
+static enum hs_result hs_patch_s_params(hs_job_t *job)
{
enum hs_result result;
int len = job->cmd->len_1 + job->cmd->len_2;
@@ -135,22 +104,22 @@ static enum hs_result _hs_patch_s_params(hs_patch_job_t *job)
assert(len);
- result = _hs_scoop_readahead(job->stream, len, &p);
+ result = hs_scoop_readahead(job->stream, len, &p);
if (result != HS_OK)
return result;
/* we now must have LEN bytes buffered */
- result = _hs_suck_netint(job->stream, job->cmd->len_1, &job->param1);
+ result = hs_suck_netint(job->stream, job->cmd->len_1, &job->param1);
/* shouldn't fail, since we already checked */
assert(result == HS_OK);
if (job->cmd->len_2) {
- result = _hs_suck_netint(job->stream, job->cmd->len_2,
- &job->param2);
+ result = hs_suck_netint(job->stream, job->cmd->len_2,
+ &job->param2);
assert(result == HS_OK);
}
- job->statefn = _hs_patch_s_run;
+ job->statefn = hs_patch_s_run;
return HS_RUN_OK;
}
@@ -160,20 +129,20 @@ static enum hs_result _hs_patch_s_params(hs_patch_job_t *job)
/*
* Called when we've read in the whole command and we need to execute it.
*/
-static enum hs_result _hs_patch_s_run(hs_patch_job_t *job)
+static enum hs_result hs_patch_s_run(hs_job_t *job)
{
- _hs_trace("running command 0x%x, kind %d", job->op, job->cmd->kind);
+ hs_trace("running command 0x%x, kind %d", job->op, job->cmd->kind);
switch (job->cmd->kind) {
case HS_KIND_LITERAL:
- job->statefn = _hs_patch_s_literal;
+ job->statefn = hs_patch_s_literal;
return HS_RUN_OK;
case HS_KIND_EOF:
- job->statefn = _hs_patch_s_complete;
+ job->statefn = hs_patch_s_complete;
return HS_OK;
/* so we exit here; trying to continue causes an error */
default:
- _hs_error("bogus command 0x%02x", job->op);
+ hs_error("bogus command 0x%02x", job->op);
return HS_BAD_MAGIC;
}
}
@@ -182,7 +151,7 @@ static enum hs_result _hs_patch_s_run(hs_patch_job_t *job)
/*
* Called when trying to copy through literal data.
*/
-static enum hs_result _hs_patch_s_literal(hs_patch_job_t *job)
+static enum hs_result hs_patch_s_literal(hs_job_t *job)
{
int len;
if (job->cmd->len_1)
@@ -190,11 +159,11 @@ static enum hs_result _hs_patch_s_literal(hs_patch_job_t *job)
else
len = job->cmd->immediate;
- _hs_trace("copying %d bytes of literal data", len);
+ hs_trace("copying %d bytes of literal data", len);
- _hs_blow_copy(job->stream, len);
+ hs_blow_copy(job->stream, len);
- job->statefn = _hs_patch_s_cmdbyte;
+ job->statefn = hs_patch_s_cmdbyte;
return HS_RUN_OK;
}
@@ -202,29 +171,29 @@ static enum hs_result _hs_patch_s_literal(hs_patch_job_t *job)
/*
* Called after encountering EOF on the patch.
*/
-static enum hs_result _hs_patch_s_complete(hs_patch_job_t *UNUSED(job))
+static enum hs_result hs_patch_s_complete(hs_job_t *UNUSED(job))
{
- _hs_fatal("the patch has already finished");
+ hs_fatal("the patch has already finished");
}
/*
* Called while we're trying to read the header of the patch.
*/
-static enum hs_result _hs_patch_s_header(hs_patch_job_t *job)
+static enum hs_result hs_patch_s_header(hs_job_t *job)
{
int v;
int result;
- if ((result =_hs_suck_n32(job->stream, &v)) != HS_OK)
+ if ((result =hs_suck_n32(job->stream, &v)) != HS_OK)
return result;
if (v != HS_DELTA_MAGIC)
return HS_BAD_MAGIC;
- _hs_trace("got patch magic %#10x", v);
+ hs_trace("got patch magic %#10x", v);
- job->statefn = _hs_patch_s_cmdbyte;
+ job->statefn = hs_patch_s_cmdbyte;
return HS_RUN_OK;
}
@@ -237,13 +206,12 @@ static enum hs_result _hs_patch_s_header(hs_patch_job_t *job)
* the stream pointers. When finished, call hs_patch_finish to
* dispose of it.
*/
-hs_patch_job_t *hs_patch_begin(hs_stream_t *stream, hs_copy_cb *copy_cb,
- void *copy_arg)
+hs_job_t *hs_patch_begin(hs_stream_t *stream, hs_copy_cb *copy_cb,
+ void *copy_arg)
{
- hs_patch_job_t *job = _hs_alloc_struct(hs_patch_job_t);
+ hs_job_t *job = hs_job_new(stream);
- job->statefn = _hs_patch_s_header;
- job->dogtag = HS_PATCH_TAG;
+ job->statefn = hs_patch_s_header;
job->stream = stream;
job->copy_cb = copy_cb;
@@ -254,47 +222,3 @@ hs_patch_job_t *hs_patch_begin(hs_stream_t *stream, hs_copy_cb *copy_cb,
return job;
}
-
-/*
- * Patch iterator, called by the client as more input data or output space
- * becomes available.
- *
- * Calls whatever code is appropriate to the current state.
- *
- * When the state function is called, it knows the tube is empty, and so
- * it can go ahead and blow output as required. It might have to return
- * early if not enough input data is available.
- */
-int hs_patch_iter(hs_patch_job_t *job)
-{
- int result;
-
- _hs_patch_check(job);
-
- while (1) {
- result = _hs_tube_catchup(job->stream);
- if (result != HS_OK)
- return result;
-
- result = job->statefn(job);
- if (result != HS_RUN_OK)
- return result;
- }
-
- return result;
-}
-
-
-/*
- * Free memory used by applying a patch. This doesn't finish the work.
- * It just drops it wherever it was.
- */
-enum hs_result hs_patch_finish(hs_patch_job_t *job)
-{
- _hs_patch_check(job);
-
- _hs_bzero(job, sizeof *job);
- free(job);
-
- return HS_OK;
-}
diff --git a/prototab.h b/prototab.h
index 12a09a7..d5a5028 100644
--- a/prototab.h
+++ b/prototab.h
@@ -46,7 +46,7 @@ typedef struct hs_prototab_ent {
size_t len_1, len_2, total_size;
} hs_prototab_ent_t;
-extern const hs_prototab_ent_t _hs_prototab[];
+extern const hs_prototab_ent_t hs_prototab[];
/* FIXME: Really these should be autogenerated by the same code in
diff --git a/rdiff.c b/rdiff.c
index b235877..f775549 100644
--- a/rdiff.c
+++ b/rdiff.c
@@ -3,7 +3,7 @@
* rdiff -- generate and apply rsync signatures and deltas
* $Id$
*
- * Copyright (C) 1999, 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 1999, 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -25,7 +25,7 @@
* to the dead.
* -- Harold Bloom */
-#include "config.h"
+#include <config.h>
#include <assert.h>
#include <sys/types.h>
@@ -79,7 +79,7 @@ static void show_usage(void)
printf("Usage: %s [OPTIONS] signature OLDFILE SIGNATURE\n"
" or: %s [OPTIONS] delta SIGNATURE NEWFILE DELTA\n"
" or: %s [OPTIONS] patch OLDFILE DELTA NEWFILE\n"
- " or: %s [OPTIONS] md4 INPUT\n"
+ " or: %s [OPTIONS] sum INPUT\n"
"\n"
"Compute rsync checksums or deltas, or apply a delta.\n"
"\n"
@@ -112,20 +112,20 @@ static void process_args(int argc, char **argv)
show_usage();
exit(0);
case 'I':
- _hs_readintarg(argv[optind], optarg, &hs_inbuflen);
+ hs_readintarg(argv[optind], optarg, &hs_inbuflen);
break;
case 'O':
- _hs_readintarg(argv[optind], optarg, &hs_outbuflen);
+ hs_readintarg(argv[optind], optarg, &hs_outbuflen);
break;
case 'V':
- hs_show_version(stdout, PROGRAM);
- exit(0);
+ printf("%s (%s)\n", PROGRAM, hs_libhsync_version);
+ exit(0);
case 'L':
- hs_show_licence(stdout);
+ puts(hs_licence_string);
exit(0);
case 'v':
if (!hs_supports_trace()) {
- _hs_error("library does not support trace");
+ hs_error("library does not support trace");
}
hs_trace_set_level(LOG_DEBUG);
break;
@@ -137,25 +137,157 @@ static void process_args(int argc, char **argv)
int
main(int argc, char **argv)
{
- process_args(argc, argv);
+ process_args(argc, argv);
- argc -= optind;
- argv += optind;
+ argc -= optind;
+ argv += optind;
+
+ if (argc <= 0) {
+ ;
+ } else if (strisprefix(argv[0], "signature")) {
+ return hs_rdiff_signature(argc, argv);
+ } else if (strisprefix(argv[0], "delta")) {
+ return hs_rdiff_delta(argc, argv);
+ } else if (strisprefix(argv[0], "patch")) {
+ return hs_rdiff_patch(argc, argv);
+ } else if (strisprefix(argv[0], "sum")) {
+ return hs_rdiff_sum(argc, argv);
+ }
- if (argc <= 0) {
- ;
- } else if (strisprefix(argv[0], "signature")) {
- return hs_rdiff_signature(argc, argv);
- } else if (strisprefix(argv[0], "delta")) {
- return hs_rdiff_delta(argc, argv);
- } else if (strisprefix(argv[0], "patch")) {
- return hs_rdiff_patch(argc, argv);
- } else if (strisprefix(argv[0], "md4")) {
- return hs_rdiff_md4(argc, argv);
+ hs_error("You must specify one of the signature, delta, "
+ "patch or sum operations"
+ ", or try --help.");
+ return 1;
+}
+
+
+
+/* This should probably be a parameter to all functions instead, but
+ * I'm not sure I want to keep it. */
+extern int output_mode;
+
+enum hs_result hs_rdiff_sum(int argc, char **argv)
+{
+#if 0
+ unsigned char result[HS_MD4_LENGTH];
+ char result_str[HS_MD4_LENGTH * 3];
+ FILE *in_file;
+
+ if (argc != 2) {
+ hs_error("Sum operation needs one filename");
+ return 1;
}
- _hs_error("You must specify one of the signature, delta, "
- "patch or sum operations"
- ", or try --help.");
- return 1;
+ in_file = hs_file_open(argv[1], O_RDONLY);
+
+ hs_mdfour_file(in_file, result);
+ hs_hexify(result_str, result, HS_MD4_LENGTH);
+
+ printf("%s\n", result_str);
+
+ return 0;
+#else
+ hs_fatal("not implemented at the moment, back soon");
+#endif
+}
+
+
+
+hs_result
+hs_rdiff_delta(int argc, char **argv)
+{
+#if 0
+ FILE *new_file, *sig_file, *delta_file;
+ hs_job_t *job;
+ hs_stream_t *stream;
+ char *inbuf, *outbuf;
+ hs_result result;
+
+ if (argc != 4) {
+ hs_error("Delta operation needs three filenames: "
+ "SIGNATURE NEWFILE DELTA");
+ return 1;
+ }
+
+ sig_file = hs_file_open(argv[1], O_RDONLY);
+ new_file = hs_file_open(argv[2], O_RDONLY);
+ delta_file = hs_file_open(argv[3], output_mode);
+
+ job = hs_delta_begin(stream);
+
+ /* TODO: read signatures; then close signature file. */
+ return result;
+#else
+ hs_fatal("not implemented at the moment, back soon");
+#endif
+}
+
+
+
+enum hs_result
+hs_rdiff_patch(int argc, char *argv[])
+{
+#if 0
+ FILE *old_file, *delta_file, *new_file;
+ char *outbuf;
+ HSFILE *patch;
+ enum hs_result result;
+ size_t len;
+
+ if (argc != 4) {
+ hs_error("Patch operation needs three filenames: "
+ "OLDFILE DELTA NEWFILE");
+ return 1;
+ }
+
+ old_file = hs_file_open(argv[1], O_RDONLY);
+ delta_file = hs_file_open(argv[2], O_RDONLY);
+ new_file = hs_file_open(argv[3], output_mode);
+
+ outbuf = malloc(hs_outbuflen);
+ assert(outbuf);
+ patch = hs_patch_open(old_file, delta_file);
+
+ do {
+ len = hs_outbuflen;
+ result = hs_patch_read(patch, outbuf, &len);
+ fwrite(outbuf, len, 1, new_file);
+ } while (result == HS_BLOCKED);
+
+ if (result != HS_OK)
+ goto failed;
+
+ return 0;
+
+ failed:
+ hs_error("patch failed: %s", hs_strerror(result));
+
+ return 1;
+#else
+ hs_fatal("not implemented at the moment, back soon");
+#endif
+}
+
+
+
+
+hs_result hs_rdiff_signature(int argc, char *argv[])
+{
+ FILE *old_file, *sig_file;
+ hs_result result;
+
+ if (argc != 3) {
+ hs_error("Signature operation needs two filenames");
+ return 1;
+ }
+
+ old_file = hs_file_open(argv[1], O_RDONLY);
+ sig_file = hs_file_open(argv[2], output_mode);
+
+ result = hs_whole_signature(old_file, sig_file);
+
+ if (result != HS_OK)
+ hs_error("signature failed: %s", hs_strerror(result));
+
+ return result;
}
diff --git a/readsums.c b/readsums.c
new file mode 100644
index 0000000..2eeb7a9
--- /dev/null
+++ b/readsums.c
@@ -0,0 +1,126 @@
+/*= -*- c-file-style: "linux" -*-
+ *
+ * libhsync -- the library for network deltas
+ * $Id$
+ *
+ * Copyright (C) 2001 by Martin Pool <mbp@linuxcare.com.au>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+
+#include <config.h>
+
+#include <assert.h>
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#include <sys/types.h>
+#include <limits.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+#include "hsync.h"
+#include "sumset.h"
+
+$if 0
+/*
+ * Read and remember all the signatures from last time. Return null *
+ * if there are no signatures.
+ */
+hs_sumset_t *
+hs_read_sumset(hs_read_fn_t sigread_fn, void *sigread_priv)
+{
+ int ret = 0;
+ int block_len;
+ hs_sum_buf_t *asignature;
+ int n = 0;
+ int checksum1;
+ hs_sumset_t *sumbuf;
+ uint32_t tmp32;
+
+
+ ret = hs_check_sig_version(sigread_fn, sigread_priv);
+ if (ret <= 0)
+ return NULL;
+
+ if (hs_read_blocksize(sigread_fn, sigread_priv, &block_len) < 0)
+ return NULL;
+
+ sumbuf = hs_alloc_struct(hs_sumset_t);
+
+ sumbuf->block_len = block_len;
+
+ sumbuf->block_sums = NULL;
+ /* XXX: It's perhaps a bit inefficient to realloc each time. We could
+ prealloc, but for now we'll give realloc the benefit of the doubt. */
+
+ while (1) {
+ ret = hs_read_netint(sigread_fn, sigread_priv, &tmp32);
+ checksum1 = tmp32;
+
+ if (ret == 0)
+ break;
+ if (ret < 0) {
+ hs_error("IO error while reading in signatures");
+ goto fail;
+ }
+ assert(ret == 4);
+
+ sumbuf->block_sums = realloc(sumbuf->block_sums, (n + 1) * sizeof(hs_sum_buf_t));
+ if (sumbuf->block_sums == NULL) {
+ errno = ENOMEM;
+ ret = -1;
+ break;
+ }
+ asignature = &(sumbuf->block_sums[n]);
+
+ asignature->weak_sum = checksum1;
+ asignature->i = ++n;
+
+ /* read in the long sum */
+ ret = hs_must_read(sigread_fn, sigread_priv,
+ asignature->strong_sum, DEFAULT_SUM_LENGTH);
+ if (ret != DEFAULT_SUM_LENGTH) {
+ hs_error("IO error while reading strong signature %d", n);
+ break;
+ }
+ }
+ if (ret < 0) {
+ hs_error("error reading checksums");
+ goto fail;
+ }
+
+ sumbuf->count = n;
+ hs_trace("Read %d sigs", n);
+
+ if (hs_build_hash_table(sumbuf) < 0) {
+ hs_error("error building checksum hashtable");
+ goto fail;
+ }
+
+ return sumbuf;
+
+ fail:
+ if (sumbuf)
+ free(sumbuf);
+ return NULL;
+}
+
+
+#endif
diff --git a/rollsum.c b/rollsum.c
index 6decb80..458c355 100644
--- a/rollsum.c
+++ b/rollsum.c
@@ -27,22 +27,22 @@
void
-_hs_roll_reset(hs_rollsum_t * rollsum)
+hs_roll_reset(hs_rollsum_t * rollsum)
{
hs_bzero(rollsum, sizeof *rollsum);
}
int
-_hs_stretch_sums(byte_t const *bytep, size_t full_block,
+hs_stretch_sums(byte_t const *bytep, size_t full_block,
size_t short_block, hs_rollsum_t * rollsum)
{
/* Checksum calculations are signed */
int8_t const *p = (int8_t const *) bytep;
if (!rollsum->havesum) {
- rollsum->weak_sum = _hs_calc_weak_sum(p, short_block);
- _hs_trace("recalculate checksum: weak=%#x", rollsum->weak_sum);
+ rollsum->weak_sum = hs_calc_weak_sum(p, short_block);
+ hs_trace("recalculate checksum: weak=%#x", rollsum->weak_sum);
rollsum->s1 = rollsum->weak_sum & 0xFFFF;
rollsum->s2 = rollsum->weak_sum >> 16;
} else {
@@ -68,7 +68,7 @@ _hs_stretch_sums(byte_t const *bytep, size_t full_block,
/* One byte rolls off the checksum. */
int
-_hs_trim_sums(byte_t const *bytep, hs_rollsum_t * rollsum, size_t short_block)
+hs_trim_sums(byte_t const *bytep, hs_rollsum_t * rollsum, size_t short_block)
{
/* Checksum calculations are signed */
int8_t const *p = (int8_t const *) bytep;
diff --git a/rollsum.h b/rollsum.h
index 8401de2..5fae648 100644
--- a/rollsum.h
+++ b/rollsum.h
@@ -38,10 +38,10 @@ struct hs_rollsum {
#define HS_PAINFUL_HONESTY
-int _hs_trim_sums(byte_t const *p, hs_rollsum_t * rollsum,
+int hs_trim_sums(byte_t const *p, hs_rollsum_t * rollsum,
size_t short_block);
-int _hs_stretch_sums(byte_t const *p, size_t full_block,
+int hs_stretch_sums(byte_t const *p, size_t full_block,
size_t short_block, hs_rollsum_t * rollsum);
-void _hs_roll_reset(hs_rollsum_t * rollsum);
+void hs_roll_reset(hs_rollsum_t * rollsum);
diff --git a/rsum.c b/rsum.c
new file mode 100644
index 0000000..9d5bea5
--- /dev/null
+++ b/rsum.c
@@ -0,0 +1,138 @@
+/*= -*- c-file-style: "linux" -*-
+ *
+ * libhsync -- the library for network deltas
+ * $Id$
+ *
+ * Copyright (C) 2001 by Martin Pool <mbp@linuxcare.com.au>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * rsum.c -- Command line tool to generate rsync signatures for a file.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <popt.h>
+
+#include "hsync.h"
+#include "hsyncfile.h"
+#include "fileutil.h"
+#include "util.h"
+#include "trace.h"
+
+
+#define PROGRAM "rsum"
+
+
+/* Overwrite existing files. */
+int force = 0;
+size_t block_len, sum_len;
+
+
+const struct poptOption opts[] = {
+ POPT_AUTOHELP
+ { "version", 'V', POPT_ARG_NONE, 0, 'V', "show program version" },
+ { NULL, '\0', 0, 0 }
+};
+
+
+
+static void show_usage(void)
+{
+ printf("Usage: %s [OPTIONS] OLDFILE SIGNATURE\n"
+ "\n"
+ "Compute rsync file signature.\n"
+ "\n"
+ " -v, --verbose trace internal processing\n"
+ " -I, --input-buffer=BYTES input buffer size\n"
+ " -O, --output-buffer=BYTES output buffer size\n"
+ " --help display this help and exit\n"
+ " --version output version information and exit\n"
+ " --licence show summary copying terms and exit\n"
+ ,
+ PROGRAM);
+}
+
+
+static void process_args(int argc, char **argv)
+{
+ int c, longind;
+
+ while ((c = getopt_long(argc, argv, "vfI:O:", longopts, &longind)) != -1) {
+ switch (c) {
+ case '?':
+ case ':':
+ exit(1);
+ case 'h':
+ show_usage();
+ exit(0);
+ case 'I':
+ hs_readintarg(argv[optind], optarg, &hs_inbuflen);
+ break;
+ case 'O':
+ hs_readintarg(argv[optind], optarg, &hs_outbuflen);
+ break;
+ case 'V':
+ printf("%s (%s)\n", PROGRAM, hs_libhsync_version);
+ exit(0);
+ case 'L':
+ puts(hs_licence_string);
+ exit(0);
+ case 'b':
+
+ case 'v':
+ if (!hs_supports_trace()) {
+ hs_error("library does not support trace");
+ }
+ hs_trace_set_level(LOG_DEBUG);
+ break;
+ }
+ }
+}
+
+
+int main(int argc, char *argv[])
+{
+ FILE *old_file, *sig_file;
+ hs_result result;
+
+ process_args(argc, argv);
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 3) {
+ hs_error("Signature operation needs two filenames");
+ return 1;
+ }
+
+ old_file = hs_file_open(argv[1], O_RDONLY);
+ sig_file = hs_file_open(argv[2], O_WRONLY|O_CREAT|O_TRUNC);
+
+ result = hs_whole_signature(old_file, sig_file);
+
+ if (result != HS_OK)
+ hs_error("signature failed: %s", hs_strerror(result));
+
+ return result;
+}
diff --git a/scoop.c b/scoop.c
index c26d45a..08f13b3 100644
--- a/scoop.c
+++ b/scoop.c
@@ -59,7 +59,7 @@
| -- Shihad, `The General Electric'.
*/
-#include "config.h"
+#include <config.h>
#include <assert.h>
#include <stdlib.h>
@@ -75,7 +75,7 @@
/*
* Try to accept from the input buffer to get LEN bytes in the scoop.
*/
-static void _hs_scoop_input(hs_stream_t *stream, size_t len)
+static void hs_scoop_input(hs_stream_t *stream, size_t len)
{
hs_simpl_t *impl = stream->impl;
size_t tocopy;
@@ -86,14 +86,14 @@ static void _hs_scoop_input(hs_stream_t *stream, size_t len)
/* need to allocate a new buffer, too */
char *newbuf;
int newsize = 2 * len;
- newbuf = _hs_alloc(newsize, "scoop buffer");
+ newbuf = hs_alloc(newsize, "scoop buffer");
if (impl->scoop_avail)
memcpy(newbuf, impl->scoop_next, impl->scoop_avail);
if (impl->scoop_buf)
free(impl->scoop_buf);
impl->scoop_buf = impl->scoop_next = newbuf;
impl->scoop_alloc = newsize;
- _hs_trace("resized scoop buffer to %d bytes",
+ hs_trace("resized scoop buffer to %d bytes",
impl->scoop_alloc);
} else {
/* this buffer size is fine, but move the existing
@@ -110,7 +110,7 @@ static void _hs_scoop_input(hs_stream_t *stream, size_t len)
assert(tocopy + impl->scoop_avail <= impl->scoop_alloc);
memcpy(impl->scoop_next + impl->scoop_avail, stream->next_in, tocopy);
- _hs_trace("accepted %d bytes from input to scoop", tocopy);
+ hs_trace("accepted %d bytes from input to scoop", tocopy);
impl->scoop_avail += tocopy;
stream->next_in += tocopy;
stream->avail_in -= tocopy;
@@ -126,18 +126,18 @@ static void _hs_scoop_input(hs_stream_t *stream, size_t len)
* after examining that block, we might decide to advance over all of
* it (if there is a match), or just one byte (if not).
*/
-void _hs_scoop_advance(hs_stream_t *stream, size_t len)
+void hs_scoop_advance(hs_stream_t *stream, size_t len)
{
hs_simpl_t *impl = stream->impl;
if (impl->scoop_avail) {
/* reading from the scoop buffer */
- _hs_trace("advance over %d bytes from scoop", len);
+ hs_trace("advance over %d bytes from scoop", len);
assert(len <= impl->scoop_avail);
impl->scoop_avail -= len;
impl->scoop_next += len;
} else {
- _hs_trace("advance over %d bytes from input buffer", len);
+ hs_trace("advance over %d bytes from input buffer", len);
assert(len <= stream->avail_in);
stream->avail_in -= len;
stream->next_in += len;
@@ -155,47 +155,47 @@ void _hs_scoop_advance(hs_stream_t *stream, size_t len)
*
* The data is not actually removed from the input, so this function
* lets you do readahead. If you want to keep any of the data, you
- * should also call _hs_scoop_advance to skip over it.
+ * should also call hs_scoop_advance to skip over it.
*/
-enum hs_result _hs_scoop_readahead(hs_stream_t *stream, size_t len, void **ptr)
+enum hs_result hs_scoop_readahead(hs_stream_t *stream, size_t len, void **ptr)
{
hs_simpl_t *impl = stream->impl;
- _hs_stream_check(stream);
+ hs_stream_check(stream);
if (impl->scoop_avail >= len) {
/* We have enough data queued to satisfy the request,
* so go straight from the scoop buffer. */
- _hs_trace("got %d bytes direct from scoop", len);
+ hs_trace("got %d bytes direct from scoop", len);
*ptr = impl->scoop_next;
return HS_OK;
} else if (impl->scoop_avail) {
/* We have some data in the scoop, but not enough to
* satisfy the request. */
- _hs_trace("data is present in the scoop and must be used");
- _hs_scoop_input(stream, len);
+ hs_trace("data is present in the scoop and must be used");
+ hs_scoop_input(stream, len);
if (impl->scoop_avail < len) {
- _hs_trace("still only have %d bytes in scoop, not enough",
+ hs_trace("still only have %d bytes in scoop, not enough",
impl->scoop_avail);
return HS_BLOCKED;
} else {
- _hs_trace("scoop now has %d bytes, this is enough",
+ hs_trace("scoop now has %d bytes, this is enough",
impl->scoop_avail);
*ptr = impl->scoop_next;
return HS_OK;
}
} else if (stream->avail_in >= len) {
/* There's enough data in the stream's input */
- _hs_trace("got %d bytes direct from input", len);
+ hs_trace("got %d bytes direct from input", len);
*ptr = stream->next_in;
return HS_OK;
} else {
/* Nothing was queued before, but we don't have enough
* data to satisfy the request. So queue what little
* we have, and try again next time. */
- _hs_trace("not enough data to satisfy request, scooping %d bytes",
+ hs_trace("not enough data to satisfy request, scooping %d bytes",
impl->scoop_avail);
- _hs_scoop_input(stream, len);
+ hs_scoop_input(stream, len);
return HS_BLOCKED;
}
}
@@ -206,13 +206,13 @@ enum hs_result _hs_scoop_readahead(hs_stream_t *stream, size_t len, void **ptr)
* Read LEN bytes if possible, and remove them from the input scoop.
* If there's not enough data yet, return HS_BLOCKED.
*/
-enum hs_result _hs_scoop_read(hs_stream_t *stream, size_t len, void **ptr)
+enum hs_result hs_scoop_read(hs_stream_t *stream, size_t len, void **ptr)
{
enum hs_result result;
- result = _hs_scoop_readahead(stream, len, ptr);
+ result = hs_scoop_readahead(stream, len, ptr);
if (result == HS_OK)
- _hs_scoop_advance(stream, len);
+ hs_scoop_advance(stream, len);
return result;
}
@@ -223,11 +223,11 @@ enum hs_result _hs_scoop_read(hs_stream_t *stream, size_t len, void **ptr)
* Read whatever remains in the input stream, assuming that it runs up
* to the end of the file. Set LEN appropriately.
*/
-enum hs_result _hs_scoop_read_rest(hs_stream_t *stream, size_t *len, void **ptr)
+enum hs_result hs_scoop_read_rest(hs_stream_t *stream, size_t *len, void **ptr)
{
hs_simpl_t *impl = stream->impl;
*len = impl->scoop_avail + stream->avail_in;
- return _hs_scoop_read(stream, *len, ptr);
+ return hs_scoop_read(stream, *len, ptr);
}
diff --git a/search.c b/search.c
index 893d643..48724cc 100644
--- a/search.c
+++ b/search.c
@@ -45,14 +45,14 @@
#define gettag(sum) gettag2((sum)&0xFFFF,(sum)>>16)
static int
-_hs_compare_targets(struct target const *t1, struct target const *t2)
+hs_compare_targets(struct target const *t1, struct target const *t2)
{
return ((int) t1->t - (int) t2->t);
}
int
-_hs_build_hash_table(hs_sumset_t * sums)
+hs_build_hash_table(hs_sumset_t * sums)
{
int i;
@@ -70,7 +70,7 @@ _hs_build_hash_table(hs_sumset_t * sums)
* care? */
qsort(sums->targets, sums->count,
sizeof(sums->targets[0]),
- (int (*)(const void *, const void *)) _hs_compare_targets);
+ (int (*)(const void *, const void *)) hs_compare_targets);
}
for (i = 0; i < TABLESIZE; i++)
@@ -95,7 +95,7 @@ _hs_build_hash_table(hs_sumset_t * sums)
* anything.
*/
int
-_hs_search_for_block(hs_weak_sum_t weak_sum,
+hs_search_for_block(hs_weak_sum_t weak_sum,
byte_t const *inbuf, size_t block_len,
hs_sumset_t const *sums, hs_stats_t * stats,
off_t * match_where)
@@ -128,10 +128,10 @@ _hs_search_for_block(hs_weak_sum_t weak_sum,
token = sums->block_sums[i].i;
- _hs_trace("found weak match for %08x in token %d", weak_sum, token);
+ hs_trace("found weak match for %08x in token %d", weak_sum, token);
if (!got_strong) {
- _hs_calc_strong_sum(inbuf, block_len, strong_sum,
+ hs_calc_strong_sum(inbuf, block_len, strong_sum,
DEFAULT_SUM_LENGTH);
got_strong = 1;
}
@@ -144,7 +144,7 @@ _hs_search_for_block(hs_weak_sum_t weak_sum,
*match_where = (token - 1) * sums->block_len;
return 1;
} else {
- _hs_trace("this was a false positive, the strong sums "
+ hs_trace("this was a false positive, the strong sums "
"don't match");
stats->false_matches++;
}
diff --git a/search.h b/search.h
index 98bec89..550db27 100644
--- a/search.h
+++ b/search.h
@@ -21,7 +21,7 @@
*/
int
-_hs_search_for_block(hs_weak_sum_t weak_sum,
+hs_search_for_block(hs_weak_sum_t weak_sum,
byte_t const *inbuf, size_t block_len,
hs_sumset_t const *sums, hs_stats_t * stats,
off_t * match_where);
diff --git a/snprintf.c b/snprintf.c
index 87bc7e4..18fab15 100644
--- a/snprintf.c
+++ b/snprintf.c
@@ -53,7 +53,7 @@
*
**************************************************************/
-#include "config.h"
+#include <config.h>
#include <string.h>
# include <ctype.h>
diff --git a/stats.c b/stats.c
index 9ff0c5e..686dafa 100644
--- a/stats.c
+++ b/stats.c
@@ -34,7 +34,7 @@ hs_log_stats(hs_stats_t const *stats)
char buf[1000];
hs_format_stats(stats, buf, sizeof buf - 1);
- _hs_log(LOG_INFO, "%s", buf);
+ hs_log(LOG_INFO, "%s", buf);
return 0;
}
diff --git a/stream.c b/stream.c
index 02e0c95..1888129 100644
--- a/stream.c
+++ b/stream.c
@@ -3,7 +3,7 @@
* libhsync -- dynamic caching and delta update in HTTP
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -20,9 +20,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
- /*
- * Pick a window, Jimmy, you're leaving.
- */
+ /*
+ * Programming languages should be designed not
+ * by piling feature on top of feature, but by
+ * removing the weaknesses and restrictions that
+ * make additional features appear necessary.
+ * -- Revised^5 Report on Scheme
+ */
/*
@@ -44,8 +48,8 @@
* buffer. Instead it knows that we can send either literal data, or
* data copied through from the input of the stream.
*
- * In streamfile.c you will find functions that then map buffers onto
- * stdio files.
+ * In buf.c you will find functions that then map buffers onto stdio
+ * files.
*
* So on return from an encoding function, either the input or the
* output or possibly both will have no more bytes available.
@@ -80,7 +84,7 @@
/* TODO: Return errors rather than aborting if something goes wrong. */
-#include "config.h"
+#include <config.h>
#include <assert.h>
@@ -107,10 +111,10 @@ void hs_stream_init(hs_stream_t *stream)
hs_simpl_t *impl;
assert(stream);
- _hs_bzero(stream, sizeof *stream);
+ hs_bzero(stream, sizeof *stream);
stream->dogtag = HS_STREAM_DOGTAG;
- impl = stream->impl = _hs_alloc_struct(hs_simpl_t);
+ impl = stream->impl = hs_alloc_struct(hs_simpl_t);
/* because scoop_alloc == 0, the scoop buffer will be
* allocated when required. */
@@ -121,7 +125,7 @@ void hs_stream_init(hs_stream_t *stream)
* Make sure everything is basically OK with STREAM.
*/
void
-_hs_stream_check(hs_stream_t *stream)
+hs_stream_check(hs_stream_t *stream)
{
assert(stream);
assert(stream->dogtag == HS_STREAM_DOGTAG);
@@ -134,29 +138,30 @@ _hs_stream_check(hs_stream_t *stream)
* there is not enough space in one or the other stream.
*
* This always does the copy immediately. Most functions should call
- * _hs_blow_copy to cause the copy to happen gradually as space
+ * hs_blow_copy to cause the copy to happen gradually as space
* becomes available.
*/
-int _hs_stream_copy(hs_stream_t *stream, int max_len)
+int hs_stream_copy(hs_stream_t *stream, int max_len)
{
int len = max_len;
- _hs_stream_check(stream);
+ hs_stream_check(stream);
assert(len > 0);
if ((unsigned) len > stream->avail_in) {
- _hs_trace("copy limited to %d available input bytes",
+ hs_trace("copy limited to %d available input bytes",
stream->avail_in);
len = stream->avail_in;
}
+
if ((unsigned) len > stream->avail_out) {
- _hs_trace("copy limited to %d available output bytes",
+ hs_trace("copy limited to %d available output bytes",
stream->avail_out);
len = stream->avail_out;
}
- _hs_trace("stream copied chunk of %d bytes", len);
+ hs_trace("stream copied chunk of %d bytes", len);
memcpy(stream->next_out, stream->next_in, len);
@@ -177,12 +182,12 @@ int _hs_stream_copy(hs_stream_t *stream, int max_len)
* means you're done.
*/
int
-_hs_stream_is_empty(hs_stream_t *stream)
+hs_stream_is_empty(hs_stream_t *stream)
{
- int ret = stream->avail_in == 0 && _hs_tube_is_idle(stream);
+ int ret = stream->avail_in == 0 && hs_tube_is_idle(stream);
if (ret)
- _hs_trace("stream now has no input and no tube output");
+ hs_trace("stream now has no input and no tube output");
return ret;
}
@@ -194,7 +199,7 @@ _hs_stream_is_empty(hs_stream_t *stream)
* because it has either consumed all the input or has filled the
* output buffer. This function checks that simple postcondition.
*/
-void _hs_stream_check_exit(hs_stream_t const *stream)
+void hs_stream_check_exit(hs_stream_t const *stream)
{
assert(stream->avail_in == 0 || stream->avail_out == 0);
}
diff --git a/stream.h b/stream.h
index 6cf5533..c94b7d6 100644
--- a/stream.h
+++ b/stream.h
@@ -3,7 +3,7 @@
* libhsync -- library for network deltas
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -20,6 +20,12 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+ /* Two wars in a lifetime bear hard on the little places.
+ * In winter when storms come rushing out of the dark,
+ * And the bay boils like a cauldron of sharks,
+ * The old remember the trenches at Paschendale
+ * And sons who died on the Burma Railway. */
+
/*
* Stream private data
@@ -46,21 +52,21 @@ typedef struct hs_simpl {
-int _hs_stream_is_empty(hs_stream_t *stream);
-int _hs_stream_copy(hs_stream_t *stream, int len);
-void _hs_stream_check(hs_stream_t *stream);
-void _hs_stream_check_exit(hs_stream_t const *stream);
+int hs_stream_is_empty(hs_stream_t *stream);
+int hs_stream_copy(hs_stream_t *stream, int len);
+void hs_stream_check(hs_stream_t *stream);
+void hs_stream_check_exit(hs_stream_t const *stream);
-int _hs_tube_catchup(hs_stream_t *);
-void _hs_blow_literal(hs_stream_t *, void const *buf, size_t len);
+int hs_tube_catchup(hs_stream_t *);
+void hs_blow_literal(hs_stream_t *, void const *buf, size_t len);
-void _hs_blow_copy(hs_stream_t *, int len);
+void hs_blow_copy(hs_stream_t *, int len);
-int _hs_tube_is_idle(hs_stream_t const *);
-void _hs_check_tube(hs_stream_t *);
+int hs_tube_is_idle(hs_stream_t const *);
+void hs_check_tube(hs_stream_t *);
-void _hs_scoop_advance(hs_stream_t *stream, size_t len);
-enum hs_result _hs_scoop_readahead(hs_stream_t *stream, size_t len, void **ptr);
-enum hs_result _hs_scoop_read(hs_stream_t *stream, size_t len, void **ptr);
-enum hs_result _hs_scoop_read_rest(hs_stream_t *stream, size_t *len, void **ptr);
+void hs_scoop_advance(hs_stream_t *stream, size_t len);
+enum hs_result hs_scoop_readahead(hs_stream_t *stream, size_t len, void **ptr);
+enum hs_result hs_scoop_read(hs_stream_t *stream, size_t len, void **ptr);
+enum hs_result hs_scoop_read_rest(hs_stream_t *stream, size_t *len, void **ptr);
diff --git a/streamfile.c b/streamfile.c
deleted file mode 100644
index 958d7aa..0000000
--- a/streamfile.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*= -*- c-file-style: "linux" -*-
- *
- * libhsync -- the library for network deltas
- * $Id$
- *
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "hsync.h"
-#include "trace.h"
-#include "streamfile.h"
-
-
-
-/*
- * If the stream has no more data available, read some from F into BUF,
- * and let the stream use that.
- */
-int _hs_fill_from_file(hs_stream_t *stream, char *buf, size_t buf_len, FILE *f)
-{
- /* This is only allowed if either the stream has no input buffer
- * yet, or that buffer could possibly be BUF. */
- if (stream->next_in != NULL) {
- assert(stream->avail_in <= buf_len);
- assert(stream->next_in >= buf);
- assert(stream->next_in <= buf + buf_len);
- } else {
- assert(stream->avail_in == 0);
- }
-
- if (stream->avail_in == 0 && !feof(f)) {
- int len = fread(buf, 1, buf_len, f);
- if (len < 0) {
- _hs_error("error filling stream from file: %s",
- strerror(errno));
- return HS_IO_ERROR;
- }
- stream->avail_in = len;
- stream->next_in = buf;
- }
-
- return HS_OK;
-}
-
-
-/*
- * The stream is already using BUF for an output buffer, and probably
- * contains some buffered output now. Write this out to F, and reset
- * the buffer cursor.
- */
-enum hs_result _hs_drain_to_file(hs_stream_t *stream,
- char *buf, size_t buf_len,
- FILE *f)
-{
- int present;
-
- /* This is only allowed if either the stream has no output buffer
- * yet, or that buffer could possibly be BUF. */
- if (stream->next_out == NULL) {
- assert(stream->avail_out == 0);
-
- stream->next_out = buf;
- stream->avail_out = buf_len;
-
- return HS_OK;
- }
-
- assert(stream->avail_out <= buf_len);
- assert(stream->next_out >= buf);
- assert(stream->next_out <= buf + buf_len);
-
- present = stream->next_out - buf;
- if (present > 0) {
- int result;
-
- assert(present > 0);
-
- result = fwrite(buf, 1, present, f);
- if (present != result) {
- _hs_error("error draining stream to file: %s",
- strerror(errno));
- return HS_IO_ERROR;
- }
-
- stream->next_out = buf;
- stream->avail_out = buf_len;
- }
-
- return HS_OK;
-}
diff --git a/sumset.c b/sumset.c
index 84fed6d..cc84ed7 100644
--- a/sumset.c
+++ b/sumset.c
@@ -3,7 +3,7 @@
* libhsync -- library for network deltas
* $Id$
*
- * Copyright (C) 1999, 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 1999, 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
* Copyright (C) 1999 by Andrew Tridgell
*
* This program is free software; you can redistribute it and/or modify
@@ -21,7 +21,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
+#include <config.h>
#include <assert.h>
@@ -33,109 +33,27 @@
#include <limits.h>
#include <inttypes.h>
#include <stdlib.h>
+#include <syslog.h>
#include "hsync.h"
-
-#include "sum_p.h"
-
-/*
- * Read and remember all the signatures from last time. Return null *
- * if there are no signatures.
- */
-hs_sumset_t *
-hs_read_sumset(hs_read_fn_t sigread_fn, void *sigread_priv)
-{
- int ret = 0;
- int block_len;
- hs_sum_buf_t *asignature;
- int n = 0;
- int checksum1;
- hs_sumset_t *sumbuf;
- uint32_t tmp32;
-
-
- ret = _hs_check_sig_version(sigread_fn, sigread_priv);
- if (ret <= 0)
- return NULL;
-
- if (_hs_read_blocksize(sigread_fn, sigread_priv, &block_len) < 0)
- return NULL;
-
- sumbuf = _hs_alloc_struct(hs_sumset_t);
-
- sumbuf->block_len = block_len;
-
- sumbuf->block_sums = NULL;
- /* XXX: It's perhaps a bit inefficient to realloc each time. We could
- prealloc, but for now we'll give realloc the benefit of the doubt. */
-
- while (1) {
- ret = _hs_read_netint(sigread_fn, sigread_priv, &tmp32);
- checksum1 = tmp32;
-
- if (ret == 0)
- break;
- if (ret < 0) {
- _hs_error("IO error while reading in signatures");
- goto fail;
- }
- assert(ret == 4);
-
- sumbuf->block_sums = realloc(sumbuf->block_sums, (n + 1) * sizeof(hs_sum_buf_t));
- if (sumbuf->block_sums == NULL) {
- errno = ENOMEM;
- ret = -1;
- break;
- }
- asignature = &(sumbuf->block_sums[n]);
-
- asignature->weak_sum = checksum1;
- asignature->i = ++n;
-
- /* read in the long sum */
- ret = _hs_must_read(sigread_fn, sigread_priv,
- asignature->strong_sum, DEFAULT_SUM_LENGTH);
- if (ret != DEFAULT_SUM_LENGTH) {
- _hs_error("IO error while reading strong signature %d", n);
- break;
- }
- }
- if (ret < 0) {
- _hs_error("error reading checksums");
- goto fail;
- }
-
- sumbuf->count = n;
- _hs_trace("Read %d sigs", n);
-
- if (_hs_build_hash_table(sumbuf) < 0) {
- _hs_error("error building checksum hashtable");
- goto fail;
- }
-
- return sumbuf;
-
- fail:
- if (sumbuf)
- free(sumbuf);
- return NULL;
-}
-
+#include "sumset.h"
+#include "util.h"
+#include "trace.h"
void
hs_free_sumset(hs_sumset_t * psums)
{
- if (psums->block_sums)
- free(psums->block_sums);
+ if (psums->block_sums)
+ free(psums->block_sums);
- assert(psums->tag_table);
- free(psums->tag_table);
+ assert(psums->tag_table);
+ free(psums->tag_table);
- if (psums->targets)
- free(psums->targets);
+ if (psums->targets)
+ free(psums->targets);
- hs_bzero(psums, sizeof *psums);
- free(psums);
+ hs_bzero(psums, sizeof *psums);
+ free(psums);
}
@@ -143,23 +61,23 @@ hs_free_sumset(hs_sumset_t * psums)
void
hs_sumset_dump(hs_sumset_t const *sums)
{
- int i;
- char strong_hex[MD4_LENGTH * 3];
+ int i;
+ char strong_hex[HS_MD4_LENGTH * 3];
- _hs_log(LOG_INFO,
- "sumset info: block_len=%d, file length=%lu, "
- "number of chunks=%d, remainder=%d",
- sums->block_len,
- (unsigned long) sums->flength, sums->count,
- sums->remainder);
-
- for (i = 0; i < sums->count; i++) {
- hs_hexify_buf(strong_hex, sums->block_sums[i].strong_sum,
- DEFAULT_SUM_LENGTH);
- _hs_log(LOG_INFO,
- "sum %6d: weak=%08x, strong=%s",
- i, sums->block_sums[i].weak_sum, strong_hex);
- }
+ hs_log(LOG_INFO,
+ "sumset info: block_len=%d, file length=%lu, "
+ "number of chunks=%d, remainder=%d",
+ sums->block_len,
+ (unsigned long) sums->flength, sums->count,
+ sums->remainder);
+
+ for (i = 0; i < sums->count; i++) {
+ hs_hexify(strong_hex, sums->block_sums[i].strong_sum,
+ sums->strong_sum_len);
+ hs_log(LOG_INFO,
+ "sum %6d: weak=%08x, strong=%s",
+ i, sums->block_sums[i].weak_sum, strong_hex);
+ }
}
diff --git a/sumset.h b/sumset.h
index f02f680..85a40ef 100644
--- a/sumset.h
+++ b/sumset.h
@@ -1,8 +1,9 @@
/*= -*- c-file-style: "linux" -*-
- * rproxy -- dynamic caching and delta update in HTTP
+ *
+ * libhsync -- the library for network deltas
* $Id$
*
- * Copyright (C) 1999, 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 1999, 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
* Copyright (C) 1999 by Andrew Tridgell <tridge@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or
@@ -26,14 +27,10 @@ typedef unsigned char hs_strong_sum_t[HS_MD4_LENGTH];
typedef struct hs_rollsum hs_rollsum_t;
-struct hs_target {
+typedef struct hs_target {
short t;
int i;
-};
-
-
-/* TODO: Include length of strong checksums in case it varies between
- * files. */
+} hs_target_t;
typedef struct hs_sum_buf hs_sum_buf_t;
@@ -43,13 +40,14 @@ typedef struct hs_sum_buf hs_sum_buf_t;
* search.
*/
struct hs_sumset {
- off_t flength; /* total file length */
- int count; /* how many chunks */
- int remainder; /* flength % block_length */
- int block_len; /* block_length */
- hs_sum_buf_t *block_sums; /* points to info for each chunk */
- int *tag_table;
- struct target *targets;
+ off_t flength; /* total file length */
+ int count; /* how many chunks */
+ int remainder; /* flength % block_length */
+ int block_len; /* block_length */
+ int strong_sum_len;
+ hs_sum_buf_t *block_sums; /* points to info for each chunk */
+ int *tag_table;
+ hs_target_t *targets;
};
diff --git a/trace.c b/trace.c
index d33fe83..810d5be 100644
--- a/trace.c
+++ b/trace.c
@@ -3,7 +3,7 @@
* libhsync -- library for network deltas
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -27,7 +27,7 @@
| There are lumps in it.
*/
-#include "config.h"
+#include <config.h>
#include <unistd.h>
#include <stdio.h>
@@ -45,11 +45,9 @@
#include "trace.h"
-int const hs_libhsync_file_offset_bits = SIZEOF_OFF_T * 8;
+hs_trace_fn_t *hs_trace_impl = hs_trace_stderr;
-hs_trace_fn_t *_hs_trace_impl = hs_trace_stderr;
-
-static int _hs_trace_level = LOG_INFO;
+static int hs_trace_level = LOG_INFO;
#ifdef HAVE_PROGRAM_INVOCATION_NAME
# define MY_NAME program_invocation_short_name
@@ -57,13 +55,13 @@ static int _hs_trace_level = LOG_INFO;
# define MY_NAME "libhsync"
#endif
-static void _hs_log_va(int level, char const *fn, char const *fmt, va_list va);
+static void hs_log_va(int level, char const *fn, char const *fmt, va_list va);
/* Called by the application to set the destination of trace * information. */
void
hs_trace_to(hs_trace_fn_t * new_impl)
{
- _hs_trace_impl = new_impl;
+ hs_trace_impl = new_impl;
}
@@ -71,14 +69,14 @@ hs_trace_to(hs_trace_fn_t * new_impl)
void
hs_trace_set_level(int level)
{
- _hs_trace_level = level;
+ hs_trace_level = level;
}
static void
-_hs_log_va(int level, char const *fn, char const *fmt, va_list va)
+hs_log_va(int level, char const *fn, char const *fmt, va_list va)
{
- if (_hs_trace_impl && level <= _hs_trace_level) {
+ if (hs_trace_impl && level <= hs_trace_level) {
char buf[1000];
char full_buf[1000];
@@ -87,7 +85,7 @@ _hs_log_va(int level, char const *fn, char const *fmt, va_list va)
snprintf(full_buf, sizeof full_buf - 1,
"%s: %s: %s\n", MY_NAME, fn, buf);
- _hs_trace_impl(level, full_buf);
+ hs_trace_impl(level, full_buf);
}
}
@@ -96,12 +94,12 @@ _hs_log_va(int level, char const *fn, char const *fmt, va_list va)
/* This function is called by a macro that prepends the calling function
* name, etc. */
void
-_hs_log0(int level, char const *fn, char const *fmt, ...)
+hs_log0(int level, char const *fn, char const *fmt, ...)
{
va_list va;
va_start(va, fmt);
- _hs_log_va(level, fn, fmt, va);
+ hs_log_va(level, fn, fmt, va);
va_end(va);
}
@@ -117,12 +115,12 @@ hs_trace_stderr(int UNUSED(level), char const *msg)
/* This is called directly if the machine doesn't allow varargs
* macros. */
void
-_hs_fatal0(char const *s, ...)
+hs_fatal0(char const *s, ...)
{
va_list va;
va_start(va, s);
- _hs_log_va(LOG_CRIT, PACKAGE, s, va);
+ hs_log_va(LOG_CRIT, PACKAGE, s, va);
va_end(va);
}
@@ -130,12 +128,12 @@ _hs_fatal0(char const *s, ...)
/* This is called directly if the machine doesn't allow varargs
* macros. */
void
-_hs_error0(char const *s, ...)
+hs_error0(char const *s, ...)
{
va_list va;
va_start(va, s);
- _hs_log_va(LOG_ERR, PACKAGE, s, va);
+ hs_log_va(LOG_ERR, PACKAGE, s, va);
va_end(va);
}
@@ -143,12 +141,12 @@ _hs_error0(char const *s, ...)
/* This is called directly if the machine doesn't allow varargs
* macros. */
void
-_hs_trace0(char const *s, ...)
+hs_trace0(char const *s, ...)
{
va_list va;
va_start(va, s);
- _hs_log_va(LOG_DEBUG, PACKAGE, s, va);
+ hs_log_va(LOG_DEBUG, PACKAGE, s, va);
va_end(va);
}
@@ -161,9 +159,9 @@ _hs_trace0(char const *s, ...)
int
hs_supports_trace(void)
{
-#ifdef DO_HS_TRACE
+#ifdef DOHS_TRACE
return 1;
#else
return 0;
-#endif /* !DO_HS_TRACE */
+#endif /* !DOHS_TRACE */
}
diff --git a/trace.h b/trace.h
index 7bb70f7..1d898af 100644
--- a/trace.h
+++ b/trace.h
@@ -36,21 +36,21 @@
* fatal terminates the whole process
*/
-void _hs_fatal0(char const *s, ...);
-void _hs_error0(char const *s, ...);
-void _hs_trace0(char const *s, ...);
+void hs_fatal0(char const *s, ...);
+void hs_error0(char const *s, ...);
+void hs_trace0(char const *s, ...);
#ifdef __GNUC__
-void _hs_log0(int level, char const *fn, char const *fmt, ...)
+void hs_log0(int level, char const *fn, char const *fmt, ...)
__attribute__ ((format(printf, 3, 4)));
#ifdef DO_HS_TRACE
-# define _hs_trace(fmt, arg...) \
- do { _hs_log0(LOG_DEBUG, __FUNCTION__, fmt , ##arg); \
+# define hs_trace(fmt, arg...) \
+ do { hs_log0(LOG_DEBUG, __FUNCTION__, fmt , ##arg); \
} while (0)
#else
-# define _hs_trace(s, str...)
+# define hs_trace(s, str...)
#endif /* !DO_HS_TRACE */
/*
@@ -62,18 +62,18 @@ void _hs_log0(int level, char const *fn, char const *fmt, ...)
* whatever it's called.
*/
-#define _hs_log(l, s, str...) do { \
- _hs_log0(l, __FUNCTION__, (s) , ##str); \
+#define hs_log(l, s, str...) do { \
+ hs_log0(l, __FUNCTION__, (s) , ##str); \
} while (0)
-#define _hs_error(s, str...) do { \
- _hs_log0(LOG_ERR, __FUNCTION__, (s) , ##str); \
+#define hs_error(s, str...) do { \
+ hs_log0(LOG_ERR, __FUNCTION__, (s) , ##str); \
} while (0)
-#define _hs_fatal(s, str...) do { \
- _hs_log0(LOG_CRIT, __FUNCTION__, \
+#define hs_fatal(s, str...) do { \
+ hs_log0(LOG_CRIT, __FUNCTION__, \
(s) , ##str); \
abort(); \
} while (0)
@@ -81,12 +81,12 @@ void _hs_log0(int level, char const *fn, char const *fmt, ...)
#else /************************* ! __GNUC__ */
-# define _hs_fatal _hs_fatal0
-# define _hs_error _hs_error0
+# define hs_fatal hs_fatal0
+# define hs_error hs_error0
# ifdef DO_HS_TRACE
-# define _hs_trace _hs_trace0
-void _hs_log0(int, char const *, ...);
+# define hs_trace hs_trace0
+void hs_log0(int, char const *, ...);
# endif /* DO_HS_TRACE */
#endif /* ! __GNUC__ */
diff --git a/tube.c b/tube.c
index ea87a8e..5321ff5 100644
--- a/tube.c
+++ b/tube.c
@@ -50,7 +50,7 @@
* possible. But for simplicity don't do that yet. */
-#include "config.h"
+#include <config.h>
#include <assert.h>
#include <stdlib.h>
@@ -66,7 +66,7 @@
const int HS_TUBE_TAG = 892138;
-static void _hs_tube_catchup_literal(hs_stream_t *stream)
+static void hs_tube_catchup_literal(hs_stream_t *stream)
{
int len, remain;
hs_simpl_t *tube = stream->impl;
@@ -79,7 +79,7 @@ static void _hs_tube_catchup_literal(hs_stream_t *stream)
len = stream->avail_out;
if (!stream->avail_out) {
- _hs_trace("no output space available");
+ hs_trace("no output space available");
return;
}
@@ -88,7 +88,7 @@ static void _hs_tube_catchup_literal(hs_stream_t *stream)
stream->avail_out -= len;
remain = tube->lit_len - len;
- _hs_trace("transmitted %d literal bytes from tube, %d remain",
+ hs_trace("transmitted %d literal bytes from tube, %d remain",
len, remain);
if (remain > 0) {
@@ -102,7 +102,7 @@ static void _hs_tube_catchup_literal(hs_stream_t *stream)
}
-static void _hs_tube_catchup_copy(hs_stream_t *stream)
+static void hs_tube_catchup_copy(hs_stream_t *stream)
{
int copied;
hs_simpl_t *tube = stream->impl;
@@ -110,11 +110,11 @@ static void _hs_tube_catchup_copy(hs_stream_t *stream)
assert(tube->lit_len == 0);
assert(tube->copy_len > 0);
- copied = _hs_stream_copy(stream, tube->copy_len);
+ copied = hs_stream_copy(stream, tube->copy_len);
tube->copy_len -= copied;
- _hs_trace("transmitted %d copy bytes from tube, %d remain",
+ hs_trace("transmitted %d copy bytes from tube, %d remain",
copied, tube->copy_len);
}
@@ -124,11 +124,11 @@ static void _hs_tube_catchup_copy(hs_stream_t *stream)
* Return HS_OK if the tube is now empty and ready to accept another
* command, HS_BLOCKED if there is still stuff waiting to go out.
*/
-int _hs_tube_catchup(hs_stream_t *stream)
+int hs_tube_catchup(hs_stream_t *stream)
{
hs_simpl_t *tube = stream->impl;
if (tube->lit_len)
- _hs_tube_catchup_literal(stream);
+ hs_tube_catchup_literal(stream);
if (tube->lit_len) {
/* there is still literal data queued, so we can't send
@@ -137,7 +137,7 @@ int _hs_tube_catchup(hs_stream_t *stream)
}
if (tube->copy_len)
- _hs_tube_catchup_copy(stream);
+ hs_tube_catchup_copy(stream);
if (tube->copy_len)
return HS_BLOCKED;
@@ -149,7 +149,7 @@ int _hs_tube_catchup(hs_stream_t *stream)
/* Check whether there is data in the tube waiting to go out. So if true
* this basically means that the previous command has finished doing all its
* output. */
-int _hs_tube_is_idle(hs_stream_t const *stream)
+int hs_tube_is_idle(hs_stream_t const *stream)
{
hs_simpl_t *tube = stream->impl;
return tube->lit_len == 0 && tube->copy_len == 0;
@@ -161,7 +161,7 @@ int _hs_tube_is_idle(hs_stream_t const *stream)
* output of the stream. We can only accept this request if there is
* no copy command already pending.
*/
-void _hs_blow_copy(hs_stream_t *stream, int len)
+void hs_blow_copy(hs_stream_t *stream, int len)
{
hs_simpl_t *tube = stream->impl;
assert(tube->copy_len == 0);
@@ -180,13 +180,13 @@ void _hs_blow_copy(hs_stream_t *stream, int len)
* tube, because the literal data comes out first.
*/
void
-_hs_blow_literal(hs_stream_t *stream, const void *buf, size_t len)
+hs_blow_literal(hs_stream_t *stream, const void *buf, size_t len)
{
hs_simpl_t *tube = stream->impl;
assert(tube->copy_len == 0);
if (len > sizeof(tube->lit_buf) - tube->lit_len) {
- _hs_fatal("tube popped when trying to blow %d literal bytes!",
+ hs_fatal("tube popped when trying to blow %d literal bytes!",
len);
}
diff --git a/util.c b/util.c
index 0998e0a..a0b4fda 100644
--- a/util.c
+++ b/util.c
@@ -25,7 +25,7 @@
*/
-#include "config.h"
+#include <config.h>
#include <stdlib.h>
#include <stdio.h>
@@ -34,33 +34,33 @@
#include "trace.h"
void
-_hs_bzero(void *buf, size_t size)
+hs_bzero(void *buf, size_t size)
{
memset(buf, 0, size);
}
void *
-_hs_alloc_struct0(size_t size, char const *name)
+hs_alloc_struct0(size_t size, char const *name)
{
void *p;
if (!(p = malloc(size))) {
- _hs_fatal("couldn't allocate instance of %s", name);
+ hs_fatal("couldn't allocate instance of %s", name);
}
- _hs_bzero(p, size);
+ hs_bzero(p, size);
return p;
}
void *
-_hs_alloc(size_t size, char const *name)
+hs_alloc(size_t size, char const *name)
{
void *p;
if (!(p = malloc(size))) {
- _hs_fatal("couldn't allocate instance of %s", name);
+ hs_fatal("couldn't allocate instance of %s", name);
}
return p;
@@ -69,7 +69,7 @@ _hs_alloc(size_t size, char const *name)
void
-_hs_readintarg(char const *opt, char const *arg, int *out)
+hs_readintarg(char const *opt, char const *arg, int *out)
{
char *o;
diff --git a/util.h b/util.h
index ede9c58..4dc0217 100644
--- a/util.h
+++ b/util.h
@@ -22,20 +22,20 @@
*/
-void * _hs_alloc(size_t size, char const *name);
-void *_hs_alloc_struct0(size_t size, char const *name);
+void * hs_alloc(size_t size, char const *name);
+void *hs_alloc_struct0(size_t size, char const *name);
-void _hs_bzero(void *buf, size_t size);
+void hs_bzero(void *buf, size_t size);
/*
* Allocate and zero-fill an instance of TYPE.
*/
-#define _hs_alloc_struct(type) \
- ((type *) _hs_alloc_struct0(sizeof(type), #type))
+#define hs_alloc_struct(type) \
+ ((type *) hs_alloc_struct0(sizeof(type), #type))
-void _hs_readintarg(char const *opt, char const *arg, int *out);
+void hs_readintarg(char const *opt, char const *arg, int *out);
diff --git a/version.c b/version.c
index fe9466a..184a9b7 100644
--- a/version.c
+++ b/version.c
@@ -3,7 +3,7 @@
* libhsync -- dynamic caching and delta update in HTTP
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -20,43 +20,26 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
+#include <config.h>
#include <stdio.h>
#include "hsync.h"
-char const * const hs_libhsync_version = PACKAGE " " VERSION;
-
-
-void hs_show_version(FILE *out, char const *program)
-{
- fprintf(out,
-"%s (%s) %s (%d-bit, trace %s, %s)\n"
-"\n"
-"Copyright (C) 1997-2000 by Martin Pool, Andrew Tridgell and others.\n"
-"This is free software; see the GNU General Public Licence version 2.1\n"
-"or later for copying conditions. There is NO warranty of any kind.\n"
-,
- program, PACKAGE, VERSION,
- hs_libhsync_file_offset_bits,
- hs_supports_trace() ? "enabled" : "disabled",
- HS_CANONICAL_HOST
- );
-}
+char const hs_libhsync_version[] = (PACKAGE " " VERSION
+ " [" __DATE__ " " __TIME__ "]");
/*
- * This little function is dedicated to Stephen Kapp and Reaper
- * Technologies, who (apparently) tried to redistribute a modified
- * version of GNU Keyring in violation of the licence and all laws of
- * politeness and good taste.
+ * This little declaration is dedicated to Stephen Kapp and Reaper
+ * Technologies, who by all appearances redistributed a modified but
+ * unacknowledged version of GNU Keyring in violation of the licence
+ * and all laws of politeness and good taste.
*/
-void hs_show_licence(FILE *out)
-{
- fprintf(out,
-"Copyright (C) 1997-2000 by Martin Pool, Andrew Tridgell and others.\n"
+char const hs_licence_string[] =
+"http://rproxy.samba.org/\n"
+"Copyright (C) 1997-2001 by Martin Pool, Andrew Tridgell and others.\n"
"\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU Lesser General Public License\n"
@@ -70,6 +53,4 @@ void hs_show_licence(FILE *out)
"\n"
"You should have received a copy of the GNU Lesser General Public\n"
"License along with this program; if not, write to the Free Software\n"
-"Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
- );
-}
+"Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n";
diff --git a/whole.c b/whole.c
index 66d9ab2..9bcffaf 100644
--- a/whole.c
+++ b/whole.c
@@ -3,7 +3,7 @@
* libhsync -- the library for network deltas
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2000, 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -20,6 +20,15 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+ /*
+ * Is it possible that software is not
+ * like anything else, that it is meant
+ * to be discarded: that the whole point
+ * is to always see it as a soap bubble?
+ * -- Alan Perlis
+ */
+
+
/*
* whole.c -- This module contains routines for processing whole files
@@ -28,162 +37,72 @@
* they are.
*/
-#include "config.h"
+#include <config.h>
#include <assert.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
-#include <sys/file.h>
#include <string.h>
-#include <syslog.h>
+
#include <errno.h>
#include "trace.h"
#include "fileutil.h"
#include "hsync.h"
#include "hsyncfile.h"
+#include "job.h"
+#include "buf.h"
+#include "whole.h"
-/* This should probably be a parameter to all functions instead, but
- * I'm not sure I want to keep it. */
-extern int output_mode;
-
-enum hs_result
-hs_rdiff_delta(int argc, char **argv)
+/*
+ * Run a job continuously, with input to/from the two specified files.
+ * The job should already be set up.
+ */
+hs_result
+hs_whole_run(hs_job_t *job, FILE *in_file, FILE *out_file)
{
- FILE *new_file, *sig_file, *delta_file;
-
- if (argc != 4) {
- _hs_error("Delta operation needs three filenames: "
- "SIGNATURE NEWFILE DELTA");
- return 1;
- }
-
- _hs_fatal("no longer implemented");
-}
+ hs_stream_t *stream = job->stream;
+ hs_result result, iores;
+ hs_filebuf_t *in_fb, *out_fb;
+ int ending = 0;
+ in_fb = hs_filebuf_new(in_file, stream, hs_inbuflen);
+ out_fb = hs_filebuf_new(out_file, stream, hs_outbuflen);
-enum hs_result hs_rdiff_md4(int argc, char **argv)
-{
- unsigned char result[HS_MD4_LENGTH];
- char result_str[HS_MD4_LENGTH * 3];
- FILE *in_file;
- char *inbuf = malloc(hs_inbuflen);
- int len;
- hs_mdfour_t md4;
-
- if (argc != 2) {
- _hs_error("MD4 operation needs one filename");
- return 1;
- }
-
- in_file = _hs_file_open(argv[1], O_RDONLY);
- assert(inbuf);
-
- hs_mdfour_begin(&md4);
- while (!feof(in_file)) {
- len = fread(inbuf, hs_inbuflen, 1, in_file);
- if (len < 0) {
- _hs_fatal("%s: %s", argv[1], strerror(errno));
- return 1;
- }
- hs_mdfour_update(&md4, inbuf, len);
- }
-
- hs_mdfour_result(&md4, result);
- hs_hexify(result_str, result, HS_MD4_LENGTH);
-
- printf("%s\n", result_str);
-
- return 0;
+ do {
+ iores = hs_infilebuf_fill(in_fb);
+ if (iores != HS_OK)
+ return iores;
+
+ result = hs_job_iter(job, ending);
+ if (result != HS_OK && result != HS_BLOCKED)
+ return result;
+
+ iores = hs_outfilebuf_drain(out_fb);
+ if (iores != HS_OK)
+ return iores;
+ } while (result != HS_OK);
+
+ return result;
}
-
-enum hs_result hs_rdiff_patch(int argc, char *argv[])
+hs_result
+hs_whole_signature(FILE *old_file, FILE *sig_file, size_t new_block_len,
+ size_t strong_len)
{
- FILE *old_file, *delta_file, *new_file;
- char *outbuf;
- HSFILE *patch;
- enum hs_result result;
- size_t len;
-
- if (argc != 4) {
- _hs_error("Patch operation needs three filenames: "
- "OLDFILE DELTA NEWFILE");
- return 1;
- }
-
- old_file = _hs_file_open(argv[1], O_RDONLY);
- delta_file = _hs_file_open(argv[2], O_RDONLY);
- new_file = _hs_file_open(argv[3], output_mode);
-
- outbuf = malloc(hs_outbuflen);
- assert(outbuf);
- patch = hs_patch_open(old_file, delta_file);
+ hs_result result;
+ hs_job_t *job;
+ hs_stream_t stream;
- do {
- len = hs_outbuflen;
- result = hs_patch_read(patch, outbuf, &len);
- fwrite(outbuf, len, 1, new_file);
- } while (result == HS_BLOCKED);
-
- if (result != HS_OK)
- goto failed;
-
- return 0;
-
- failed:
- _hs_error("patch failed: %s", hs_strerror(result));
-
- return 1;
-}
+ hs_stream_init(&stream);
+ job = hs_mksum_begin(&stream, new_block_len, strong_len);
+ result = hs_whole_run(job, old_file, sig_file);
+ hs_job_free(job);
-
-enum hs_result hs_rdiff_signature(int argc, char *argv[])
-{
- FILE *old_file, *sig_file;
- char *inbuf;
- HSFILE *mksum;
- int len;
- enum hs_result result;
-
- if (argc != 3) {
- _hs_error("Signature operation needs two filenames");
- return 1;
- }
-
- old_file = _hs_file_open(argv[1], O_RDONLY);
- sig_file = _hs_file_open(argv[2], output_mode);
-
- inbuf = malloc(hs_inbuflen);
- mksum = hs_mksum_open(sig_file, HS_DEFAULT_BLOCK_LEN,
- HS_DEFAULT_STRONG_LEN);
-
- do {
- len = fread(inbuf, 1, hs_inbuflen, old_file);
- if (len < 0) {
- _hs_error("%s: %s", argv[1], strerror(errno));
- return 1;
- }
-
- _hs_trace("got %d bytes from input file", len);
- result = hs_mksum_write(mksum, inbuf, len);
- if (result != HS_BLOCKED && result != HS_OK)
- goto failed;
- } while (!feof(old_file));
-
- result = hs_mksum_close(mksum);
- if (result != HS_OK)
- goto failed;
-
- return 0;
-
- failed:
- _hs_error("signature failed: %s", hs_strerror(result));
-
- return 1;
+ return result;
}
diff --git a/streamfile.h b/whole.h
index 2895d0d..1c9b77c 100644
--- a/streamfile.h
+++ b/whole.h
@@ -3,7 +3,7 @@
* libhsync -- the library for network deltas
* $Id$
*
- * Copyright (C) 2000 by Martin Pool <mbp@linuxcare.com.au>
+ * Copyright (C) 2001 by Martin Pool <mbp@linuxcare.com.au>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -20,8 +20,5 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-enum hs_result _hs_fill_from_file(hs_stream_t *stream,
- char *buf, size_t buf_len, FILE *f);
-enum hs_result _hs_drain_to_file(hs_stream_t *stream,
- char *buf, size_t buf_len, FILE *f);
+hs_result hs_whole_run(hs_job_t *job, FILE *in_file, FILE *out_file);