summaryrefslogtreecommitdiffstats
path: root/src
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 /src
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
Diffstat (limited to 'src')
-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
23 files changed, 328 insertions, 88 deletions
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);