From 37621a019f8fb5e0ac2e506b45279ab7ba67a167 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 3 Dec 2004 15:41:48 +0000 Subject: assorted stuff git-svn-id: file:///home/lennart/svn/public/syrep/trunk@75 07ea20a6-d2c5-0310-9e02-9ef735347d72 --- src/forget.c | 4 ++-- src/merge.c | 58 ++++++++++++++++++++++++++++++++++++++++++---------------- src/syrep.ggo | 1 + src/util.c | 18 ++++++++---------- 4 files changed, 53 insertions(+), 28 deletions(-) diff --git a/src/forget.c b/src/forget.c index befcf3f..1983f2f 100644 --- a/src/forget.c +++ b/src/forget.c @@ -156,7 +156,7 @@ finish: } int forget(struct syrep_db_context *c, struct syrep_db_context *target) { - uint32_t t; + time_t t; time_t now, limit; assert(c && target); @@ -166,7 +166,7 @@ int forget(struct syrep_db_context *c, struct syrep_db_context *target) { return -1; } - t = args.remember_arg*24*60*60; + t = (time_t) args.remember_arg*24*60*60; time(&now); limit = t > now ? 0 : now-t; diff --git a/src/merge.c b/src/merge.c index 4c77e43..a6c303d 100644 --- a/src/merge.c +++ b/src/merge.c @@ -149,6 +149,28 @@ static int conflict_phase(DB *ddb, struct syrep_name *name, struct diff_entry *d return 0; } +static int do_copy(const char *a, const char *b) { + int (*copy_proc) (const char *, const char*, int c) = args.always_copy_flag ? copy_file : copy_or_link_file; + + if (!args.always_replace_flag) { + int r, q; + + if ((r = copy_proc(a, b, 0)) >= 0) + return r; + + if (errno != EEXIST) + return r; + + if (!(q = question("Replace existing file?", "ny"))) + return -1; + + if (q != 'y') + return -1; + } + + return copy_proc(a, b, 1); +} + static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) { struct cb_info *cb_info = p; struct syrep_name name2; @@ -158,9 +180,6 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v 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) @@ -203,18 +222,21 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v if (makeprefixpath(path, 0777) < 0) return -1; - if (!access(path2, R_OK)) { - if (copy_proc(path2, path, 0) < 0) + if (do_copy(path2, path) < 0) { + if (errno != ENOENT) { + fprintf(stderr, "COPY: Failed to copy file '%s' to '%s': %s\n", path2, path, strerror(errno)); return -1; - } else { - snprintf(path2, sizeof(path2), "%s/%s", cb_info->trash_dir, name2.path); - - if (!access(path2, R_OK)) { - 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); - return -1; + snprintf(path2, sizeof(path2), "%s/%s", cb_info->trash_dir, name2.path); + + if (do_copy(path2, path) < 0) { + if (errno == ENOENT) + fprintf(stderr, "COPY: Local file <%s> vanished. Snapshot not up to date\n", name2.path); + else + fprintf(stderr, "COPY: Failed to copy file '%s' to '%s': %s\n", path2, path, strerror(errno)); + + return -1; + } } } @@ -244,7 +266,7 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v if (makeprefixpath(path, 0777) < 0) return -1; - if (copy_proc(a, path, de->action == DIFF_REPLACE) < 0) + if (do_copy(a, path) < 0) return -1; } else if (args.verbose_flag) @@ -313,8 +335,12 @@ static int delete_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, if (makeprefixpath(target, 0777) < 0) return -1; - if (move_file(path, target, 1) < 0) - return -1; + if (move_file(path, target, 1) < 0) { + if (errno == ENOENT && !access(target, F_OK)) + fprintf(stderr, "DELETE: File is probably already in trash, continuing\n"); + else + return -1; + } if (args.prune_empty_flag) prune_empty_directories(path, cb_info->root); diff --git a/src/syrep.ggo b/src/syrep.ggo index 53c60ae..79c6cd5 100644 --- a/src/syrep.ggo +++ b/src/syrep.ggo @@ -52,6 +52,7 @@ option "merge" - "Merge a snapshot or a repository into a repository" 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 "always-replace" - "merge: Always replace existing files" 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/util.c b/src/util.c index 715a7b5..10135ba 100644 --- a/src/util.c +++ b/src/util.c @@ -125,9 +125,8 @@ void rotdash_hide(void) { const char* get_attached_filename(const char *root, const char *fn) { static char npath[PATH_MAX]; - snprintf(npath, sizeof(npath), "%s/.syrep", root); - mkdir(npath, 0777); snprintf(npath, sizeof(npath), "%s/.syrep/%s", root, fn); + makeprefixpath(npath, 0777); return npath; } @@ -164,7 +163,7 @@ int isdirectory(const char *path) { #ifdef USE_SENDFILE -#define MAX_SENDFILE_SIZE (1024*1024*1024) /* A gigabyte */ +#define MAX_SENDFILE_SIZE (1024L*1024L*1024L) /* A gigabyte */ static int copy_fd_sendfile(int sfd, int dfd, off_t l) { off_t sfo, o; @@ -195,7 +194,6 @@ static int copy_fd_sendfile(int sfd, int dfd, off_t l) { #endif - off_t filesize(int fd) { struct stat st; @@ -210,10 +208,10 @@ off_t filesize(int fd) { int expand_file(int fd, off_t l) { off_t s; - if ((s = filesize(fd)) < 0) + if ((s = filesize(fd)) == (off_t) -1) return -1; - if (s < l) + if (l > s) if (ftruncate(fd, l) < 0) { fprintf(stderr, "ftruncate(): %s\n", strerror(errno)); return -1; @@ -222,8 +220,8 @@ int expand_file(int fd, off_t l) { return 0; } -#define MMAPSIZE (100*1024*1024) /* 100MB */ -#define BUFSIZE (32*1024) +#define MMAPSIZE (20*1024*1024) /* 20MB */ +#define BUFSIZE (64*1024) int copy_fd(int sfd, int dfd, off_t l) { off_t sfo = 0, dfo = 0, msfo = 0, mdfo = 0; @@ -232,7 +230,7 @@ int copy_fd(int sfd, int dfd, off_t l) { static size_t psize = 0; #ifdef USE_SENDFILE - if (copy_fd_sendfile(sfd, dfd, l) == 0) + if (copy_fd_sendfile(sfd, dfd, l) >= 0) return 0; if (errno == ENOSPC) @@ -258,7 +256,7 @@ int copy_fd(int sfd, int dfd, off_t l) { if ((s = filesize(sfd)) < 0) return -1; - if (s < sfo+l) { + if (sfo+l > s) { fprintf(stderr, "File too short\n"); return -1; } -- cgit