From b6abf79d60722dbee89e6270435d0b11c0dffa91 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 30 Nov 2003 14:27:42 +0000 Subject: 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 --- src/cache.c | 6 ++- src/cleanup.c | 4 ++ src/context.c | 4 ++ src/dbstruct.h | 6 +-- src/dbutil.c | 15 +++++++- src/dbutil.h | 1 + src/diff.c | 4 ++ src/dump.c | 4 ++ src/extract.c | 4 ++ src/history.c | 4 ++ src/info.c | 8 +++- src/list.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++------- src/makepatch.c | 6 ++- src/md5.c | 4 ++ src/md5util.c | 30 ++++++++++++++- src/md5util.h | 4 +- src/merge.c | 82 ++++++++++++++++++++++++++++++--------- src/merge.h | 2 +- src/package.c | 4 ++ src/syrep.c | 83 +++++++++++++++++++++------------------- src/syrep.ggo | 5 ++- src/update.c | 7 +++- src/util.c | 12 ++++-- 23 files changed, 328 insertions(+), 88 deletions(-) (limited to 'src') 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 +#endif + #include #include #include @@ -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 +#endif + #include #include #include 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 +#endif + #include #include #include 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 +#endif + #include #include #include @@ -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 +#endif + #include #include #include 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 +#endif + #include #include #include 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 +#endif + #include #include #include 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 +#endif + #include #include #include 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 +#endif + #include #include +#include #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 +#endif + #include #include #include @@ -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 +#endif + #include #include #include @@ -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 +#endif + #include "md5.h" #include 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 +#endif + #include #include #include @@ -25,12 +29,13 @@ #include #include #include +#include #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 +#endif + #include #include #include @@ -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 +#endif + #include #include #include 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 +#endif + #include #include #include @@ -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...] [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 +#endif + #include #include #include @@ -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 +#endif + #include #include #include @@ -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); -- cgit