summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2003-11-30 14:27:42 +0000
committerLennart Poettering <lennart@poettering.net>2003-11-30 14:27:42 +0000
commitb6abf79d60722dbee89e6270435d0b11c0dffa91 (patch)
treed40783bd9c86b989e9f2ddb4a0dc63f9592d74f0
parentc0d1779760fd10d14344fa1ed70b91bdf50272c1 (diff)
relase 0.3
--copy-always --sort bi-directory merges --check-md git-svn-id: file:///home/lennart/svn/public/syrep/trunk@43 07ea20a6-d2c5-0310-9e02-9ef735347d72
-rw-r--r--configure.ac19
-rw-r--r--doc/README.html.in8
-rw-r--r--doc/todo.txt8
-rw-r--r--man/syrep.1.xml.in47
-rw-r--r--man/xmltoman.css (renamed from man/man.css)8
-rw-r--r--man/xmltoman.dtd39
-rw-r--r--man/xmltoman.xsl (renamed from man/man.xsl)10
-rw-r--r--src/cache.c6
-rw-r--r--src/cleanup.c4
-rw-r--r--src/context.c4
-rw-r--r--src/dbstruct.h6
-rw-r--r--src/dbutil.c15
-rw-r--r--src/dbutil.h1
-rw-r--r--src/diff.c4
-rw-r--r--src/dump.c4
-rw-r--r--src/extract.c4
-rw-r--r--src/history.c4
-rw-r--r--src/info.c8
-rw-r--r--src/list.c117
-rw-r--r--src/makepatch.c6
-rw-r--r--src/md5.c4
-rw-r--r--src/md5util.c30
-rw-r--r--src/md5util.h4
-rw-r--r--src/merge.c82
-rw-r--r--src/merge.h2
-rw-r--r--src/package.c4
-rw-r--r--src/syrep.c83
-rw-r--r--src/syrep.ggo5
-rw-r--r--src/update.c7
-rw-r--r--src/util.c12
-rw-r--r--test/Makefile2
31 files changed, 438 insertions, 119 deletions
diff --git a/configure.ac b/configure.ac
index b139740..b1e0fb4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -31,8 +31,13 @@ AC_PROG_LN_S
AC_SUBST(PACKAGE_URL, [http://0pointer.de/lennart/projects/syrep/])
-if test -d /usr/local/stow ; then
- AC_MSG_NOTICE([*** Found /usr/local/stow: installing to /usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION} ***])
+# If using GCC specifiy some additional parameters
+if test "x$GCC" = "xyes" ; then
+ CFLAGS="$CFLAGS -pipe -Wall"
+fi
+
+if type -p stow > /dev/null && test -d /usr/local/stow ; then
+ AC_MSG_NOTICE([*** Found /usr/local/stow: default install prefix set to /usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION} ***])
AC_PREFIX_DEFAULT([/usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION}])
fi
@@ -49,22 +54,20 @@ AC_CHECK_HEADER([sys/sendfile.h], sendfile=yes, sendfile=no)
if test "x$sendfile" = xyes ; then
AC_CHECK_LIB([c], [sendfile], sendfile=yes, sendfile=no)
- CPPFLAGS="$CPPFLAGS -DUSE_SENDFILE"
+ AC_DEFINE([USE_SENDFILE], [1], [Use sendfile()])
fi
AM_CONDITIONAL([USE_SENDFILE], [test "x$sendfile" = xyes])
-
AC_C_BIGENDIAN
-
if test "x$ac_cv_c_bigendian" = "xyes"; then
- CFLAGS="$CPPFLAGS -DARCH_IS_BIG_ENDIAN=1"
+ AC_DEFINE([ARCH_IS_BIG_ENDIAN], [1], [Big Endian machine])
else
- CPPFLAGS="$CPPFLAGS -DARCH_IS_BIG_ENDIAN=0"
+ AC_DEFINE([ARCH_IS_BIG_ENDIAN], [0], [Big Endian machine])
fi
# 64 Bit LFS support
-CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64"
+AC_SYS_LARGEFILE
AC_HEADER_DIRENT
AC_HEADER_STDC
diff --git a/doc/README.html.in b/doc/README.html.in
index 3a9d750..896e28a 100644
--- a/doc/README.html.in
+++ b/doc/README.html.in
@@ -42,6 +42,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.</p>
<h2><a name="news">News</a></h2>
+<div class="news-date">Sun Nov 30 2003: </div> <p class="news-text"><a
+href="@PACKAGE_URL@syrep-0.3.tar.gz">Version 0.3</a> released; Changes
+include: new options <tt>--sort</tt>, <tt>--check-md</tt>,
+<tt>--always-copy</tt>; implemented direct bi-directory merges,
+documentation updates, build system updates, assorted fixes.</p>
+
<div class="news-date">Tue Sep 9 2003: </div> <p class="news-text"><a
href="@PACKAGE_URL@syrep-0.2.tar.gz">Version
0.2</a> released; Fixes include: documentation update, <tt>--diff</tt> output improved, <tt>--merge</tt> output fixed.</p>
@@ -221,7 +227,7 @@ L. Peter Deutsch. Thanks to him for this.</p>
<hr/>
-<address>Lennart Poettering &lt;@PACKAGE_BUGREPORT@&gt;, Sep 2003</address>
+<address>Lennart Poettering &lt;@PACKAGE_BUGREPORT@&gt;, Nov 2003</address>
<div><i>$Id$</i></div>
diff --git a/doc/todo.txt b/doc/todo.txt
index 9870198..762843c 100644
--- a/doc/todo.txt
+++ b/doc/todo.txt
@@ -26,11 +26,11 @@ pre-0.1:
post-0.1:
- continue merge on copy failure
- url/ssh merges
-- bi-directory merges
-- digest check before delete/replace/link
+- bi-directory merges DONE
+- digest check before delete/replace/link DONE
- some more asserts
-- PATH_MAX or PATH_MAX+1?
-- add --always-copy
+- PATH_MAX or PATH_MAX+1? DONE
+- add --always-copy DONE
- add --forget
- valgrind
diff --git a/man/syrep.1.xml.in b/man/syrep.1.xml.in
index 2b6e502..ce946b7 100644
--- a/man/syrep.1.xml.in
+++ b/man/syrep.1.xml.in
@@ -1,6 +1,6 @@
<?xml version="1.0"?> <!-- -*-xae-*- -->
-<!DOCTYPE manpage SYSTEM "man.dtd">
-<?xml-stylesheet type="text/xsl" href="man.xsl" ?>
+<!DOCTYPE manpage SYSTEM "xmltoman.dtd">
+<?xml-stylesheet type="text/xsl" href="xmltoman.xsl" ?>
<!-- $Id$ -->
@@ -32,9 +32,11 @@
<cmd>syrep [<opt>options...</opt>] <opt>--update</opt> <arg>DIRECTORY</arg> ...</cmd>
<cmd>syrep [<opt>options...</opt>] <opt>--diff</opt> <arg>SNAPSHOT</arg> <arg>SNAPSHOT</arg></cmd>
<cmd>syrep [<opt>options...</opt>] <opt>--merge</opt> <arg>SNAPSHOT</arg> <arg>DIRECTORY</arg></cmd>
+ <cmd>syrep [<opt>options...</opt>] <opt>--merge</opt> <arg>PATCH</arg> <arg>DIRECTORY</arg></cmd>
+ <cmd>syrep [<opt>options...</opt>] <opt>--merge</opt> <arg>DIRECTORY</arg> <arg>DIRECTORY</arg></cmd>
<cmd>syrep [<opt>options...</opt>] <opt>--makepatch</opt> <arg>DIRECTORY</arg> <arg>SNAPSHOT</arg></cmd>
<cmd>syrep [<opt>options...</opt>] <opt>--extract</opt> <arg>SNAPSHOT</arg> ...</cmd>
- <cmd>syrep [<opt>options...</opt>] <opt>--cleanup</opt> <arg>SNAPSHOT</arg> ...</cmd>
+ <cmd>syrep [<opt>options...</opt>] <opt>--cleanup</opt> <arg>DIRECTORY</arg> ...</cmd>
</synopsis>
<description>
@@ -55,7 +57,18 @@
<p>Syrep is able to cope with 64 bit file sizes. (LFS)</p>
- <p>Syrep is optimized for speed. It may make use of a message digest cache to accelerate the calculation of digests of a whole directory hierarchy.</p>
+ <p>Syrep is optimized for speed. It may make use of a message
+ digest cache to accelerate the calculation of digests of a whole
+ directory hierarchy.</p>
+
+ <p>A syrep repository is a normal UNIX directory tree containing a
+ special directory <file>.syrep</file> with a file
+ <file>current.syrep</file> (called snapshot) which holds file
+ system history data. A directory is turned into a syrep repository
+ by running <opt>--update</opt> on it. Snapshots are used to
+ perform basic tasks like comparing repositories (command
+ <opt>--diff</opt>) or creating patches between them (command
+ <opt>--make-patch</opt>).</p>
</description>
@@ -121,7 +134,7 @@
<option>
<p><opt>--show-by-md</opt> (option)</p>
- <optdesc>Show files by message digests</optdesc>
+ <optdesc>Show files by message digests. This option collides with <opt>--sort</opt>.</optdesc>
</option>
<option>
@@ -129,6 +142,11 @@
<optdesc>Show first and last seen times</optdesc>
</option>
+ <option>
+ <p><opt>--sort</opt> (option)</p>
+ <optdesc>Sort file listing chronologically. This option collides with <opt>--show-by-md</opt>.</optdesc>
+ </option>
+
</section>
<section name="Showing snapshot information">
@@ -184,23 +202,36 @@
</option>
</section>
- <section name="Merging a snapshot into a directory">
+ <section name="Merging a snapshot, a patch or a repository into a repository">
<option>
<p><opt>--merge</opt> (command)</p>
- <optdesc>Merge a snapshot or a patch into a repository. Afterwards, you should run <opt>--update</opt> on the repository to update the snapshot.</optdesc>
+ <optdesc>Merge a snapshot, a patch or a repository into a repository. Afterwards, you should run <opt>--update</opt> on the repository to update the snapshot.</optdesc>
</option>
<option>
<p><opt>-q</opt> | <opt>--question</opt> (option)</p>
<optdesc>Ask a question before each action</optdesc>
</option>
<option>
- <p><opt>--prune-empty</opt> (option)</p>
+ <p><opt>-P</opt> | <opt>--prune-empty</opt> (option)</p>
<optdesc>Prune empty directories</optdesc>
</option>
<option>
<p><opt>--keep-trash</opt> (option)</p>
<optdesc>Don't empty trash. Deleted files are copied into a trash folder inside the repository directory. If this option is specified this trash is not emptied when the operation is completed.</optdesc>
</option>
+ <option>
+ <p><opt>--check-md</opt> (option)</p>
+ <optdesc>Check message digests of files before deleting or replacing them. NB: This worsens syrep's performance and is thus not enabled by default.</optdesc>
+ </option>
+ <option>
+ <p><opt>--always-copy</opt> (option)</p>
+ <optdesc>As default syrep tries to hard link files instead of
+ copying them. With this option syrep will always do a copy,
+ regardless if a hard link is possible or not. This is especially
+ useful when doing bi-directory merges. NB: This worsens syrep's performance and is thus not enabled by default.
+ </optdesc>
+ </option>
+
</section>
<section name="Making a patch for a snapshot against a directory">
diff --git a/man/man.css b/man/xmltoman.css
index 37dd55f..0892e4f 100644
--- a/man/man.css
+++ b/man/xmltoman.css
@@ -1,20 +1,20 @@
/* $Id$ */
/***
- This file is part of syrep.
+ This file is part of ifplugd.
- syrep is free software; you can redistribute it and/or modify it under
+ ifplugd is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
- syrep is distributed in the hope that it will be useful, but WITHOUT
+ ifplugd 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 General Public License
for more details.
You should have received a copy of the GNU General Public License
- along with syrep; if not, write to the Free Software Foundation,
+ along with ifplugd; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***/
diff --git a/man/xmltoman.dtd b/man/xmltoman.dtd
new file mode 100644
index 0000000..39cfa28
--- /dev/null
+++ b/man/xmltoman.dtd
@@ -0,0 +1,39 @@
+<!-- $Id$ -->
+
+<!--
+ This file is part of ifplugd.
+
+ ifplugd is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ ifplugd 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 General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ifplugd; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+-->
+
+<!ELEMENT manpage (synopsis | description | section | options | seealso)*>
+<!ATTLIST manpage name CDATA #REQUIRED section CDATA #REQUIRED desc CDATA #IMPLIED>
+<!ELEMENT arg (#PCDATA)>
+<!ELEMENT p (#PCDATA | arg | url | manref | opt | file )*>
+<!ELEMENT synopsis (cmd | p)+>
+<!ELEMENT description (p)+>
+<!ELEMENT section (p | option)*>
+<!ATTLIST section name CDATA #REQUIRED>
+<!ELEMENT option (#PCDATA | p | optdesc)*>
+<!ELEMENT optdesc (#PCDATA | p )*>
+<!ELEMENT cmd (#PCDATA | arg)*>
+<!ELEMENT options (p | option)*>
+<!ELEMENT seealso (p)*>
+<!ELEMENT opt (#PCDATA)>
+<!ELEMENT file (#PCDATA)>
+<!ELEMENT manref EMPTY>
+<!ATTLIST manref name CDATA #REQUIRED section CDATA #REQUIRED href CDATA #IMPLIED>
+<!ELEMENT url EMPTY>
+<!ATTLIST url href CDATA #REQUIRED>
diff --git a/man/man.xsl b/man/xmltoman.xsl
index 7946a76..2048708 100644
--- a/man/man.xsl
+++ b/man/xmltoman.xsl
@@ -2,20 +2,20 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<!--
- This file is part of xmltoman.
+ This file is part of ifplugd.
- xmltoman is free software; you can redistribute it and/or modify it under
+ ifplugd is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
- xmltoman is distributed in the hope that it will be useful, but WITHOUT
+ ifplugd 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 General Public License
for more details.
You should have received a copy of the GNU General Public License
- along with xmltoman; if not, write to the Free Software Foundation,
+ along with ifplugd; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-->
@@ -29,7 +29,7 @@
<title>
<xsl:value-of select="@name"/>(<xsl:value-of select="@section"/>)
</title>
- <link rel="stylesheet" type="text/css" href="man.css"/>
+ <link rel="stylesheet" type="text/css" href="xmltoman.css"/>
</head>
<body>
<h1>Name</h1>
diff --git a/src/cache.c b/src/cache.c
index 925cd69..6722b55 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <db.h>
#include <stdlib.h>
#include <assert.h>
@@ -157,7 +161,7 @@ int md_cache_get(struct syrep_md_cache *c, const char *path, uint8_t digest[16])
struct stat st;
if ((fd = open(path, O_RDONLY)) < 0) {
- fprintf(stderr, "open(%s): %s\n", path, strerror(errno));
+ fprintf(stderr, "open(\"%s\"): %s\n", path, strerror(errno));
goto finish;
}
diff --git a/src/cleanup.c b/src/cleanup.c
index 6f096f9..447697d 100644
--- a/src/cleanup.c
+++ b/src/cleanup.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <unistd.h>
#include <string.h>
#include <limits.h>
diff --git a/src/context.c b/src/context.c
index 677704d..9fe37bb 100644
--- a/src/context.c
+++ b/src/context.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/src/dbstruct.h b/src/dbstruct.h
index 74c6059..842e33d 100644
--- a/src/dbstruct.h
+++ b/src/dbstruct.h
@@ -59,7 +59,7 @@ struct syrep_nhash { /* name hash */
};
struct syrep_name {
- char path[PATH_MAX+1];
+ char path[PATH_MAX];
};
@@ -69,11 +69,11 @@ struct syrep_name {
* syrep_md :: syrep_nrecno => md_nrecno (DUP)
* syrep_nrecno :: syrep_md => nrecno_md (DUP)
* syrep_nrecno :: syrep_md => nrecno_lastmd
- * syrep_md :: syrep_nrecono => md_lastnrecno
+ * syrep_md :: syrep_nrecno => md_lastnrecno
*
* syrep_version :: syrep_timestamp => version_timestamp
*
- * nhash :: nrecno => nhash_nrecno (DUP)
+ * nhash :: nrecno => nhash_nrecno (DUP)
* nrecno :: name => nrecno_name
*/
diff --git a/src/dbutil.c b/src/dbutil.c
index d7aa319..cfa3150 100644
--- a/src/dbutil.c
+++ b/src/dbutil.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <string.h>
#include <assert.h>
#include <time.h>
@@ -152,6 +156,14 @@ int get_current_md_by_nrecno(struct syrep_db_context *c, const struct syrep_nrec
return 1;
}
+int get_current_md_by_name(struct syrep_db_context *c, const struct syrep_name *name, struct syrep_md *md) {
+ struct syrep_nrecno nrecno;
+
+ if (get_nrecno_by_name(c, name, &nrecno, 0) < 0)
+ return -1;
+
+ return get_current_md_by_nrecno(c, &nrecno, md);
+}
uint32_t get_version_timestamp(struct syrep_db_context *c, uint32_t v) {
DBT key, data;
@@ -210,7 +222,8 @@ int get_name_by_nrecno(struct syrep_db_context *c, const struct syrep_nrecno *nr
if (name) {
memset(name, 0, sizeof(struct syrep_name));
- strncpy(name->path, data.data, MIN(PATH_MAX, data.size));
+ strncpy(name->path, data.data, MIN(PATH_MAX-1, data.size));
+ name->path[PATH_MAX-1] = 0;
}
return 1;
diff --git a/src/dbutil.h b/src/dbutil.h
index dd4acd2..9d9837c 100644
--- a/src/dbutil.h
+++ b/src/dbutil.h
@@ -27,6 +27,7 @@
int get_meta_by_nrecno_md(struct syrep_db_context *c, const struct syrep_nrecno*nrecno, const struct syrep_md *md, struct syrep_meta *meta);
int get_last_md_by_nrecno(struct syrep_db_context *c, const struct syrep_nrecno *nrecno, struct syrep_md *md);
int get_current_md_by_nrecno(struct syrep_db_context *c, const struct syrep_nrecno *nrecno, struct syrep_md *md);
+int get_current_md_by_name(struct syrep_db_context *c, const struct syrep_name *name, struct syrep_md *md);
int get_current_nrecno_by_md(struct syrep_db_context *c, const struct syrep_md *md, struct syrep_nrecno *nrecno);
uint32_t get_version_timestamp(struct syrep_db_context *c, uint32_t v);
diff --git a/src/diff.c b/src/diff.c
index 9a87d81..a589504 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <assert.h>
#include <string.h>
#include <stdlib.h>
diff --git a/src/dump.c b/src/dump.c
index 289478b..5a9b721 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <stdio.h>
#include <assert.h>
#include <string.h>
diff --git a/src/extract.c b/src/extract.c
index ec1d8f0..2e63d14 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
diff --git a/src/history.c b/src/history.c
index 4da91d5..ff8532e 100644
--- a/src/history.c
+++ b/src/history.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <assert.h>
#include <string.h>
#include <time.h>
diff --git a/src/info.c b/src/info.c
index 14446c2..a35877c 100644
--- a/src/info.c
+++ b/src/info.c
@@ -18,16 +18,22 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <stdio.h>
#include <assert.h>
+#include <time.h>
#include "info.h"
#include "util.h"
int info(struct syrep_db_context *c) {
+ time_t t = (time_t) c->timestamp;
assert(c);
fprintf(stdout, "Origin: %s\n", c->origin);
- fprintf(stdout, "Timestamp: %u; %s", c->timestamp, asctime(localtime(&c->timestamp)));
+ fprintf(stdout, "Timestamp: %u; %s", c->timestamp, asctime(localtime(&t)));
fprintf(stdout, "Version: %u\n", c->version);
fprintf(stdout, "Database nrecno_meta: ");
statistics(c->db_id_meta);
diff --git a/src/list.c b/src/list.c
index e5fe62f..f1763eb 100644
--- a/src/list.c
+++ b/src/list.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <string.h>
#include <assert.h>
#include <stdlib.h>
@@ -30,17 +34,21 @@
#include "dbutil.h"
#include "syrep.h"
-static int handle_file(struct syrep_db_context *c, const struct syrep_nrecno *nrecno, const struct syrep_md *md, const struct syrep_meta *meta) {
+static int handle_file(struct syrep_db_context *c, const struct syrep_nrecno *nrecno, const struct syrep_md *md, const struct syrep_meta *meta, const struct syrep_name *name) {
struct syrep_meta local_meta;
- struct syrep_name name;
- int f;
+ struct syrep_name local_name;
assert(c && nrecno && md);
- if ((f = get_name_by_nrecno(c, nrecno, &name)) < 0)
- return -1;
+ if (!name) {
+ int f;
+
+ if ((f = get_name_by_nrecno(c, nrecno, &local_name)) < 0)
+ return -1;
- assert(f);
+ assert(f);
+ name = &local_name;
+ }
if (!meta) {
int f;
@@ -60,9 +68,9 @@ static int handle_file(struct syrep_db_context *c, const struct syrep_nrecno *nr
fhex(md->digest, SYREP_DIGESTLENGTH, d);
d[SYREP_DIGESTLENGTH*2] = 0;
- printf("%s %s%s", d, name.path, meta->last_seen == c->version ? "\t\t" : "\t(deleted)");
+ printf("%s %s%s", d, name->path, meta->last_seen == c->version ? "\t\t" : "\t(deleted)");
} else
- printf("\t%s%s", name.path, meta->last_seen == c->version ? "\t\t" : "\t(deleted)");
+ printf("\t%s%s", name->path, meta->last_seen == c->version ? "\t\t" : "\t(deleted)");
if (args.show_times_flag)
printf( "\t(first-seen: %u; last-seen: %u)\n", meta->first_seen, meta->last_seen);
@@ -73,16 +81,44 @@ static int handle_file(struct syrep_db_context *c, const struct syrep_nrecno *nr
fhex(md->digest, SYREP_DIGESTLENGTH, d);
d[SYREP_DIGESTLENGTH*2] = 0;
- printf("\t%s", name.path);
+ printf("\t%s", name->path);
}
return 0;
}
+struct sort_entry {
+ struct syrep_nrecno nrecno;
+ struct syrep_md md;
+ struct syrep_meta meta;
+ struct syrep_name name;
+};
+
+static int sort_entry_cmp(const void *_a, const void *_b) {
+ const struct sort_entry *a = _a, *b = _b;
+ assert(a && b);
+
+ if (a->meta.last_seen < b->meta.last_seen)
+ return -1;
+
+ if (a->meta.last_seen > b->meta.last_seen)
+ return 1;
+
+ if (a->meta.first_seen < b->meta.first_seen)
+ return -1;
+
+ if (a->meta.first_seen > b->meta.first_seen)
+ return 1;
+
+ return strncmp(a->name.path, b->name.path, PATH_MAX);
+};
+
int list(struct syrep_db_context *c) {
int r = -1, ret;
DBC *cursor = NULL;
DBT key, data;
+ struct sort_entry *sort_array = NULL;
+ unsigned n_sort_array = 0, m_sort_array = 0;
if (args.show_by_md_flag) {
struct syrep_md previous_md;
@@ -112,7 +148,7 @@ int list(struct syrep_db_context *c) {
if ((ret = get_meta_by_nrecno_md(c, recno, md, &meta)) < 0)
goto finish;
- if (handle_file(c, recno, md, &meta) < 0)
+ if (handle_file(c, recno, md, &meta, NULL) < 0)
fprintf(stderr, "handle_file() failed\n");
}
@@ -123,7 +159,7 @@ int list(struct syrep_db_context *c) {
r = 0;
} else {
-
+
if ((ret = c->db_id_meta->cursor(c->db_id_meta, NULL, &cursor, 0)) != 0) {
c->db_id_meta->err(c->db_id_meta, ret, "id_meta");
goto finish;
@@ -135,9 +171,59 @@ int list(struct syrep_db_context *c) {
while ((ret = cursor->c_get(cursor, &key, &data, DB_NEXT)) == 0) {
struct syrep_id *id = (struct syrep_id*) key.data;
- if (handle_file(c, &id->nrecno, &id->md, (struct syrep_meta*) data.data) < 0)
- fprintf(stderr, "handle_file() failed\n");
-
+ if (!args.sort_flag) {
+ if (handle_file(c, &id->nrecno, &id->md, (struct syrep_meta*) data.data, NULL) < 0)
+ fprintf(stderr, "handle_file() failed\n");
+
+ } else {
+ if (n_sort_array >= m_sort_array) {
+
+ if (!m_sort_array) {
+ DB_BTREE_STAT *statp;
+ int ret;
+
+ if ((ret = c->db_id_meta->stat(c->db_id_meta, &statp, 0)) != 0)
+ break;
+
+ m_sort_array = statp->bt_ndata;
+ free(statp);
+ } else
+ m_sort_array *= 2;
+
+ sort_array = realloc(sort_array, m_sort_array * sizeof(struct sort_entry));
+ }
+
+ assert(n_sort_array < m_sort_array);
+
+ if (get_name_by_nrecno(c, &id->nrecno, &sort_array[n_sort_array].name) != 1)
+ goto finish;
+
+ memcpy(&sort_array[n_sort_array].nrecno, &id->nrecno, sizeof(struct syrep_nrecno));
+ memcpy(&sort_array[n_sort_array].md, &id->md, sizeof(struct syrep_md));
+ memcpy(&sort_array[n_sort_array].meta, data.data, sizeof(struct syrep_meta));
+ n_sort_array++;
+ }
+
+ if (interrupted) {
+ fprintf(stderr, "Canceled.\n");
+ goto finish;
+ }
+ }
+
+ if (args.sort_flag && sort_array) {
+ unsigned i;
+ struct sort_entry *se;
+ qsort(sort_array, n_sort_array, sizeof(struct sort_entry), sort_entry_cmp);
+
+ for (i = 0, se = sort_array; i < n_sort_array; i++, se++) {
+ if ((handle_file(c, &se->nrecno, &se->md, &se->meta, &se->name)) < 0)
+ fprintf(stderr, "handle_file() failed\n");
+
+ if (interrupted) {
+ fprintf(stderr, "Canceled.\n");
+ goto finish;
+ }
+ }
}
if (ret != DB_NOTFOUND) {
@@ -153,5 +239,8 @@ finish:
if (cursor)
cursor->c_close(cursor);
+ if (sort_array)
+ free(sort_array);
+
return r;
}
diff --git a/src/makepatch.c b/src/makepatch.c
index 3de8860..bbce369 100644
--- a/src/makepatch.c
+++ b/src/makepatch.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <assert.h>
#include <unistd.h>
#include <string.h>
@@ -38,7 +42,7 @@ static int cb(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p)
struct cb_info *cb_info = p;
struct syrep_md md;
struct syrep_nrecno nrecno;
- char path[PATH_MAX+1];
+ char path[PATH_MAX];
char d[SYREP_DIGESTLENGTH*2+1];
int f, k;
diff --git a/src/md5.c b/src/md5.c
index 2c9c2fc..f294588 100644
--- a/src/md5.c
+++ b/src/md5.c
@@ -51,6 +51,10 @@
1999-05-03 lpd Original version.
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include "md5.h"
#include <string.h>
diff --git a/src/md5util.c b/src/md5util.c
index 6b9a1e2..27c6dd3 100644
--- a/src/md5util.c
+++ b/src/md5util.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>
@@ -25,12 +29,13 @@
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
+#include <fcntl.h>
#include "md5util.h"
#include "md5.h"
#include "syrep.h"
-void fhex(const unsigned char *bin,int len, char *txt) {
+void fhex(const unsigned char *bin, int len, char *txt) {
const static char hex[] = "0123456789abcdef";
int i;
@@ -43,7 +48,7 @@ void fhex(const unsigned char *bin,int len, char *txt) {
#define MMAPSIZE (100*1024*1024)
#define BUFSIZE (1024*1024)
-int fdmd5(int fd, size_t l, char *md) {
+int fdmd5(int fd, off_t l, char *md) {
void *d;
off_t o = 0;
size_t m;
@@ -59,6 +64,9 @@ int fdmd5(int fd, size_t l, char *md) {
goto finish;
}
+ if (l == (off_t) -1)
+ l = pre.st_size;
+
if (l > BUFSIZE) {
m = l < MMAPSIZE ? l : MMAPSIZE;
@@ -127,3 +135,21 @@ finish:
return r;
}
+
+int fmd5(const char *fn, char *md) {
+ int fd = -1, r = -1;
+
+ if ((fd = open(fn, O_RDONLY)) < 0) {
+ fprintf(stderr, "open(\"%s\"): %s\n", fn, strerror(errno));
+ goto finish;
+ }
+
+ r = fdmd5(fd, (off_t) -1, md);
+
+finish:
+
+ if (fd >= 0)
+ close(fd);
+
+ return r;
+}
diff --git a/src/md5util.h b/src/md5util.h
index f5a342a..373d0b8 100644
--- a/src/md5util.h
+++ b/src/md5util.h
@@ -26,6 +26,8 @@
void fhex(const unsigned char *bin, int len, char *txt);
#define fhex_md5(bin,txt) fhex((bin),16,(txt))
-int fdmd5(int fd, size_t l, char *md);
+int fdmd5(int fd, off_t l, char *md);
+
+int fmd5(const char *fn, char *md);
#endif
diff --git a/src/merge.c b/src/merge.c
index 5741d83..c095f1f 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <stdio.h>
#include <assert.h>
#include <string.h>
@@ -35,10 +39,11 @@
#include "util.h"
struct cb_info {
- struct syrep_db_context *c1;
- struct syrep_db_context *c2;
- const char *root;
- char trash_dir[PATH_MAX+1];
+ struct syrep_db_context *c1; /* remote */
+ struct syrep_db_context *c2; /* local */
+ const char *root; /* directory wherein to merge files */
+ const char *sroot; /* An optional source directory for bi-directory merges */
+ char trash_dir[PATH_MAX];
};
static int conflict_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) {
@@ -47,7 +52,7 @@ static int conflict_phase(DB *ddb, struct syrep_name *name, struct diff_entry *d
struct syrep_nrecno nrecno1, nrecno2;
int writeback = 0;
int f1, f2;
- char path[PATH_MAX+1];
+ char path[PATH_MAX];
assert(ddb && name && de && p);
@@ -172,10 +177,13 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v
struct syrep_name name2;
struct syrep_nrecno nrecno, nrecno2;
struct syrep_md md;
- char path[PATH_MAX+1];
+ char path[PATH_MAX];
int f;
char d[SYREP_DIGESTLENGTH*2+1];
+ int (*copy_proc) (const char *, const char*, int c) = args.always_copy_flag ? copy_file : copy_or_link_file;
+
+
assert(ddb && name && de && p);
if (de->action != DIFF_COPY && de->action != DIFF_REPLACE)
@@ -209,7 +217,7 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v
return -1;
if (f) {
- char path2[PATH_MAX+1];
+ char path2[PATH_MAX];
snprintf(path2, sizeof(path2), "%s/%s", cb_info->root, name2.path);
if (args.verbose_flag)
@@ -219,7 +227,7 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v
return -1;
if (!access(path2, R_OK)) {
- if (copy_or_link_file(path2, path, 0) < 0)
+ if (copy_proc(path2, path, 0) < 0)
return -1;
} else {
unsigned l;
@@ -229,27 +237,39 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v
escape_path(name2.path, path2+l, sizeof(path2)-l);
if (!access(path2, R_OK)) {
- if (copy_or_link_file(path2, path, de->action == DIFF_REPLACE) < 0)
+ if (copy_proc(path2, path, de->action == DIFF_REPLACE) < 0)
return -1;
} else
fprintf(stderr, "COPY: Local file <%s> vanished. Snapshot not up to date.\n", name2.path);
}
} else {
+ char spath[PATH_MAX];
const char* a;
+ const char* t;
int k;
if ((k = package_get_item(cb_info->c1->package, d, 0, &a)) < 0)
return -1;
+ t = "patch";
+
+ if (!k && cb_info->sroot) {
+ snprintf(spath, sizeof(spath), "%s/%s", cb_info->sroot, name->path);
+ a = spath;
+
+ if ((k = (access(spath, R_OK) == 0)))
+ t = "tree";
+ }
+
if (k) {
if (args.verbose_flag)
- fprintf(stderr, "COPY: Copying file <%s> from patch.\n", name->path);
+ fprintf(stderr, "COPY: Copying file <%s> from %s.\n", name->path, t);
if (makeprefixpath(path, 0777) < 0)
return -1;
- if (copy_or_link_file(a, path, de->action == DIFF_REPLACE) < 0)
+ if (copy_proc(a, path, de->action == DIFF_REPLACE) < 0)
return -1;
} else
if (args.verbose_flag)
@@ -261,17 +281,43 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v
static int delete_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) {
struct cb_info *cb_info = p;
- char path[PATH_MAX+1], target[PATH_MAX+1];
+ char path[PATH_MAX], target[PATH_MAX];
unsigned l;
assert(ddb && name && de && p);
- if (de->action != DIFF_DELETE)
+ if (de->action != DIFF_DELETE && de->action != DIFF_REPLACE)
+ return 0;
+
+ if (de->action == DIFF_DELETE && de->repository == cb_info->c1)
return 0;
- if (de->repository == cb_info->c1)
+ if (de->action == DIFF_REPLACE && de->repository == cb_info->c2)
return 0;
+ snprintf(path, sizeof(path), "%s/%s", cb_info->root, name->path);
+
+ if (args.check_md_flag) {
+ uint8_t digest[16];
+ struct syrep_md md;
+
+ if (fmd5(path, digest) < 0) {
+ fprintf(stderr, "Unable to calculate message digest sum on '%s'\n", name->path);
+ return -1;
+ }
+
+ if (get_current_md_by_name(cb_info->c2,
+ name, &md) < 0) {
+ fprintf(stderr, "Failed to get current MD by name of '%s'\n", name->path);
+ return -1;
+ }
+
+ if (memcmp(md.digest, digest, 16) != 0) {
+ fprintf(stderr, "Message digest of file to delete doesn't match snapshot data for '%s'.\n", name->path);
+ return -1;
+ }
+ }
+
if (args.question_flag) {
char text[256];
int q;
@@ -285,8 +331,6 @@ static int delete_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de,
return 0;
}
- snprintf(path, sizeof(path), "%s/%s", cb_info->root, name->path);
-
snprintf(target, sizeof(target), "%s/", cb_info->trash_dir);
l = strlen(target);
escape_path(name->path, target+l, sizeof(target)-l);
@@ -303,8 +347,9 @@ static int delete_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de,
return 0;
}
-/* Merges c1 into c2 in directory "root" */
-int merge(struct syrep_db_context *c1, struct syrep_db_context *c2, const char* root) {
+/* Merges c1 into c2 in directory "root"
+ * sroot is an optional source directory, only used on bi-directory merges */
+int merge(struct syrep_db_context *c1, struct syrep_db_context *c2, const char* root, const char* sroot) {
struct cb_info cb_info;
DB *ddb = NULL;
int r = -1;
@@ -313,6 +358,7 @@ int merge(struct syrep_db_context *c1, struct syrep_db_context *c2, const char*
cb_info.c1 = c1;
cb_info.c2 = c2;
cb_info.root = root;
+ cb_info.sroot = sroot;
snprintf(cb_info.trash_dir, sizeof(cb_info.trash_dir), "%s/.syrep/trash", root);
mkdir_p(cb_info.trash_dir, 0777);
diff --git a/src/merge.h b/src/merge.h
index 02c1a9e..33acf11 100644
--- a/src/merge.h
+++ b/src/merge.h
@@ -23,7 +23,7 @@
#include "context.h"
-int merge(struct syrep_db_context *c1, struct syrep_db_context *c2, const char* root);
+int merge(struct syrep_db_context *c1, struct syrep_db_context *c2, const char* root, const char* sroot);
int empty_trash(const char *trash);
#endif
diff --git a/src/package.c b/src/package.c
index 9496742..c2841ad 100644
--- a/src/package.c
+++ b/src/package.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>
diff --git a/src/syrep.c b/src/syrep.c
index e65dc1c..e063072 100644
--- a/src/syrep.c
+++ b/src/syrep.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <inttypes.h>
#include <limits.h>
#include <assert.h>
@@ -53,10 +57,6 @@
#include "makepatch.h"
#include "cleanup.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "svn-revision.h"
volatile int interrupted = 0;
@@ -165,7 +165,7 @@ static int do_merge(void) {
if (db_context_origin_warn(c2))
goto finish;
- if (merge(c1, c2, args.inputs[1]) < 0)
+ if (merge(c1, c2, args.inputs[1], isdirectory(args.inputs[0]) > 0 ? args.inputs[0] : NULL) < 0)
goto finish;
r = 0;
@@ -478,53 +478,58 @@ static int help(const char *argv0) {
"Usage: %s [options...] <command> [arguments...]\n\n"
"General options:\n"
- " -v --verbose Enable verbose operation\n"
- " -T --local-temp Use temporary directory inside repository\n"
- " --ignore-origin Don't warn if snapshot not local in update, merge, makepatch\n"
- " -z --compress Compress snapshots or patches\n"
- " -p --progress Show progress\n\n"
+ " -v --verbose Enable verbose operation\n"
+ " -T --local-temp Use temporary directory inside repository\n"
+ " --ignore-origin Don't warn if snapshot not local in update, merge, makepatch\n"
+ " -z --compress Compress snapshots or patches\n"
+ " -p --progress Show progress\n\n"
"General commands:\n"
- " -h --help Print help and exit\n"
- " -V --version Print version and exit\n\n"
+ " -h --help Print help and exit\n"
+ " -V --version Print version and exit\n\n"
"Specific commands:\n"
- " --list List a repository snapshot\n"
- " --show-deleted Show deleted entries of repository snapshot\n"
- " --show-by-md Show files by message digests\n"
- " --show-times Show first and last seen times\n\n"
+ " --list SNAPSHOT List a repository snapshot\n"
+ " --show-deleted Show deleted entries of repository snapshot\n"
+ " --show-by-md Show files by message digests\n"
+ " --show-times Show first and last seen times\n"
+ " --sort Sort chronologically\n\n"
- " --info Show information about a repository or snapshot\n\n"
+ " --info SNAPSHOT Show information about a repository or snapshot\n\n"
- " --history Show history of a repository or snapshot\n\n"
+ " --history SNAPSHOT Show history of a repository or snapshot\n\n"
- " --dump Show a structure dump of a repository or snapshot\n\n"
+ " --dump SNAPSHOT Show a structure dump of a repository or snapshot\n\n"
- " --update Update a repository snapshot\n"
- " -SSTRING --snapshot=STRING Use the specified snapshot file instead of the one contained in the repository\n"
- " -CSTRING --cache=STRING Use the specified cache file instead of the one contained in the repository\n"
- " --no-cache Don't use a message digest cache\n"
- " --no-purge Don't purge obsolete entries from cache after update run\n"
- " --ro-cache Use read only cache\n\n"
+ " --update DIRECTORY Update (or create) a repository snapshot\n"
+ " -SSTRING --snapshot=STRING Use the specified snapshot file instead of the one contained in the repository\n"
+ " -CSTRING --cache=STRING Use the specified cache file instead of the one contained in the repository\n"
+ " --no-cache Don't use a message digest cache\n"
+ " --no-purge Don't purge obsolete entries from cache after update run\n"
+ " --ro-cache Use read only cache\n\n"
- " --diff Show difference between two repositories or snapshots\n\n"
+ " --diff SNAPSHOT SNAPSHOT Show difference between two repositories or snapshots\n\n"
- " --merge Merge a snapshot or a patch into a repository\n"
- " -q --question Ask a question before each action\n"
- " --prune-empty Prune empty directories\n"
- " --keep-trash Don't empty trash\n\n"
+ " --merge SNAPSHOT DIRECTORY Merge a snapshot into a repository (perform deletes, renames only)\n"
+ " --merge PATCH DIRECTORY Merge a patch into a repository\n"
+ " --merge DIRECTORY DIRECTORY Merge a repository into a repository\n"
+ " -q --question Ask a question before each action\n"
+ " -P --prune-empty Prune empty directories\n"
+ " --keep-trash Don't empty trash\n"
+ " --check-md Check message digest of files prior to deletion or replacement\n"
+ " --always-copy Always copy instead of hard link\n\n"
- " --makepatch Make a patch against the specified repository\n"
- " -oSTRING --output-file=STRING Write output to specified file instead of STDOUT\n"
- " --include-all Include files in patch which do exist on the other side under a different name\n\n"
+ " --makepatch DIRECTORY SNAPSHOT Make a patch against the specified repository\n"
+ " -oSTRING --output-file=STRING Write output to specified file instead of STDOUT\n"
+ " --include-all Include files in patch which do exist on the other side under a different name\n\n"
- " --extract Extract the contents of a snapshot or patch\n"
- " -DSTRING --output-directory=STRING Write output to specified directory\n\n"
+ " --extract SNAPSHOT Extract the contents of a snapshot or patch\n"
+ " -DSTRING --output-directory=STRING Write output to specified directory\n\n"
- " --cleanup Remove syrep info from repository\n"
- " -lINT --cleanup-level=INT 1 - just remove temporary data and trash (default)\n"
- " 2 - remove MD cache as well\n"
- " 3 - remove all syrep data\n",
+ " --cleanup DIRECTORY Remove syrep info from repository\n"
+ " -lINT --cleanup-level=INT 1 - just remove temporary data and trash (default)\n"
+ " 2 - remove MD cache as well\n"
+ " 3 - remove all syrep data\n",
argv0, argv0);
return 0;
diff --git a/src/syrep.ggo b/src/syrep.ggo
index fea530c..5156944 100644
--- a/src/syrep.ggo
+++ b/src/syrep.ggo
@@ -29,6 +29,7 @@ option "list" - "List a repository snapshot" flag off
option "show-deleted" - "list: Show deleted entries of repository snapshot" flag off
option "show-by-md" - "list: Show files by message digests" flag off
option "show-times" - "list: Show first and last seen times" flag off
+ option "sort" - "list: sort chronologically" flag off
option "info" - "Show information about a repository or snapshot" flag off
option "history" - "Show history of a repository or snapshot" flag off
@@ -46,8 +47,10 @@ option "diff" - "Show difference between two repositories or snapshots" flag off
option "merge" - "Merge a snapshot or a repository into a repository" flag off
option "question" q "merge: Ask a question before each action" flag off
- option "prune-empty" - "merge: Prune empty directories" flag off
+ option "prune-empty" P "merge: Prune empty directories" flag off
option "keep-trash" - "merge: Don't empty trash" flag off
+ option "check-md" - "merge: Check message digest of file before deleting or replacing" flag off
+ option "always-copy" - "merge: Always copy instead of hard linking" flag off
option "makepatch" - "Make a patch against the specified repository" flag off
option "output-file" o "makepatch: Write output to specified file instead of STDOUT" string no
diff --git a/src/update.c b/src/update.c
index 06986f9..6fc2d06 100644
--- a/src/update.c
+++ b/src/update.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
@@ -104,7 +108,8 @@ static int handle_file(struct syrep_db_context *c, uint32_t version, const char
struct syrep_nrecno nrecno;
memset(&name, 0, sizeof(name));
- strncpy(name.path, path, PATH_MAX);
+ strncpy(name.path, path, PATH_MAX-1);
+ name.path[PATH_MAX-1] = 0;
if ((r = get_nrecno_by_name(c, &name, &nrecno, 0)) < 0)
return -1;
diff --git a/src/util.c b/src/util.c
index ffc5dc3..5361e70 100644
--- a/src/util.c
+++ b/src/util.c
@@ -18,6 +18,10 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
@@ -499,11 +503,11 @@ int prune_empty_directories(const char *path, const char *root) {
char rroot[PATH_MAX],
rpath[PATH_MAX];
- strncpy(rroot, root, PATH_MAX);
+ strncpy(rroot, root, PATH_MAX-1);
rroot[PATH_MAX-1] = 0;
normalize_path(rroot);
- strncpy(rpath, path, PATH_MAX);
+ strncpy(rpath, path, PATH_MAX-1);
rpath[PATH_MAX-1] = 0;
normalize_path(rpath);
@@ -545,7 +549,7 @@ int mkdir_p(const char *path, mode_t m) {
char *e, *b;
int quit = 0;
- strncpy(tmp, path, PATH_MAX);
+ strncpy(tmp, path, PATH_MAX-1);
tmp[PATH_MAX-1] = 0;
normalize_path(tmp);
@@ -582,7 +586,7 @@ int mkdir_p(const char *path, mode_t m) {
int makeprefixpath(const char *path, mode_t m) {
char tmp[PATH_MAX], *e;
- strncpy(tmp, path, PATH_MAX);
+ strncpy(tmp, path, PATH_MAX-1);
tmp[PATH_MAX-1] = 0;
normalize_path(tmp);
diff --git a/test/Makefile b/test/Makefile
index 39c51ae..54e8d32 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -4,7 +4,7 @@ ifdef VERBOSE
VERBOSE=-v
endif
-ARGS+=-z -T --output-directory=extract -opatch --show-deleted --show-times --prune-empty
+ARGS+=--sort --check-md -z -T --output-directory=extract -opatch --show-deleted --show-times --prune-empty
%:
@mkdir -p rep1 rep2