From 8f0e7bc19ba5c407e7890dc17f65258ca57c51bb Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 24 Nov 2009 11:07:18 -0800 Subject: [PATCH] cpdup - Add -F, add code to remove need for FreeBSD ports patch * Add -F, allow arbitrary options to be passed to ssh. * Ignore UFS2 snapshots (FreeBSD) * Add missing #include (FreeBSD) Submitted-by: Oliver Fromme --- bin/cpdup/cpdup.1 | 9 +++++---- bin/cpdup/cpdup.c | 40 ++++++++++++++++++++++++++++++++++++---- bin/cpdup/cpdup.h | 4 ++++ bin/cpdup/hclink.c | 6 ++++-- bin/cpdup/misc.c | 3 ++- 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/bin/cpdup/cpdup.1 b/bin/cpdup/cpdup.1 index 4d4d25b73b..73f7a5054a 100644 --- a/bin/cpdup/cpdup.1 +++ b/bin/cpdup/cpdup.1 @@ -1,10 +1,8 @@ -.\" (c) Copyright 1997-1999 by Matthew Dillon and Dima Ruban. Permission to +.\" (c) Copyright 1997-2009 by Matthew Dillon and Dima Ruban. Permission to .\" use and distribute based on the DragonFly copyright. Supplied as-is, .\" USE WITH EXTREME CAUTION. .\" -.\" -.\" $DragonFly: src/bin/cpdup/cpdup.1,v 1.31 2008/05/30 18:00:23 swildner Exp $ -.Dd April 11, 2008 +.Dd November 24, 2009 .Dt CPDUP 1 .Os .Sh NAME @@ -17,6 +15,7 @@ .Op Fl u .Op Fl I .Op Fl f +.Op Fl F .Op Fl s0 .Op Fl i0 .Op Fl j0 @@ -98,6 +97,8 @@ the option is used, this option will force a byte for byte comparison between the original file and the file in the hardlink path, even if all the stat info matches, but will still use a hardlink if they match. +.It Fl F +Pass to ssh. For example '-F-p222'. Note the lack of a space. .It Fl s0 Disable the disallow-file-replaces-directory safety feature. This safety feature is enabled by default to prevent user mistakes from blowing diff --git a/bin/cpdup/cpdup.c b/bin/cpdup/cpdup.c index 0441ef519c..144856b7d0 100644 --- a/bin/cpdup/cpdup.c +++ b/bin/cpdup/cpdup.c @@ -147,6 +147,8 @@ int ValidateOpt; int CurParallel; int MaxParallel = -1; int HardLinkCount; +int ssh_argc; +const char *ssh_argv[16]; int RunningAsUser; int RunningAsRoot; const char *UseCpFile; @@ -250,6 +252,11 @@ main(int ac, char **av) case 'H': UseHLPath = (*ptr) ? ptr : av[++i]; break; + case 'F': + if (ssh_argc >= 16) + fatal("too many -F options"); + ssh_argv[ssh_argc++] = (*ptr) ? ptr : av[++i]; + break; case 'S': SlaveOpt = v; break; @@ -647,6 +654,11 @@ DoCopy(copy_info_t info, int depth) r = 0; goto done; } +#ifdef SF_SNAPSHOT + /* skip snapshot files because they're sparse and _huge_ */ + if (st1.st_flags & SF_SNAPSHOT) + return(0); +#endif st2.st_mode = 0; /* in case lstat fails */ st2.st_flags = 0; /* in case lstat fails */ if (dpath && hc_lstat(&DstHost, dpath, &st2) == 0) { @@ -852,6 +864,7 @@ relink: } if (dpath) RemoveRecur(dpath, ddevNo); + st2Valid = 0; } /* @@ -909,16 +922,35 @@ relink: } } + /* + * When copying a directory, stop if the source crosses a mount + * point. + */ if (sdevNo != (dev_t)-1 && st1.st_dev != sdevNo) { noLoop = 1; } else { sdevNo = st1.st_dev; } - if (ddevNo != (dev_t)-1 && st2.st_dev != ddevNo) { - noLoop = 1; - } else { - ddevNo = st2.st_dev; + /* + * When copying a directory, stop if the destination crosses + * a mount point. + * + * The target directory will have been created and stat'd + * for st2 if it did not previously exist. st2Valid is left + * as a flag. If the stat failed st2 will still only have its + * default initialization. + * + * So we simply assume here that the directory is within the + * current target mount if we had to create it (aka st2Valid is 0) + * and we leave ddevNo alone. + */ + if (st2Valid) { + if (ddevNo != (dev_t)-1 && st2.st_dev != ddevNo) { + noLoop = 1; + } else { + ddevNo = st2.st_dev; + } } /* diff --git a/bin/cpdup/cpdup.h b/bin/cpdup/cpdup.h index 4017008c99..61ef9b7bf7 100644 --- a/bin/cpdup/cpdup.h +++ b/bin/cpdup/cpdup.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,9 @@ extern int CurParallel; extern int RunningAsUser; extern int RunningAsRoot; +extern int ssh_argc; +extern const char *ssh_argv[]; + extern int64_t CountSourceBytes; extern int64_t CountSourceItems; extern int64_t CountCopiedItems; diff --git a/bin/cpdup/hclink.c b/bin/cpdup/hclink.c index be0769cbf3..45e56e42c9 100644 --- a/bin/cpdup/hclink.c +++ b/bin/cpdup/hclink.c @@ -21,7 +21,7 @@ hcc_connect(struct HostConf *hc) { int fdin[2]; int fdout[2]; - const char *av[16]; + const char *av[32]; if (hc == NULL || hc->host == NULL) return(0); @@ -37,7 +37,7 @@ hcc_connect(struct HostConf *hc) /* * Child process */ - int n; + int n, m; dup2(fdin[1], 1); close(fdin[0]); @@ -50,6 +50,8 @@ hcc_connect(struct HostConf *hc) av[n++] = "ssh"; if (CompressOpt) av[n++] = "-C"; + for (m = 0; m < ssh_argc; m++) + av[n++] = ssh_argv[m]; av[n++] = "-T"; av[n++] = hc->host; av[n++] = "cpdup"; diff --git a/bin/cpdup/misc.c b/bin/cpdup/misc.c index a3e243e8bb..098f051379 100644 --- a/bin/cpdup/misc.c +++ b/bin/cpdup/misc.c @@ -158,6 +158,7 @@ fatal(const char *ctl, ...) " -u use unbuffered output for -v[vv]\n" " -I display performance summary\n" " -f force update even if files look the same\n" + " -F Add to options passed to ssh\n" " -i0 do NOT confirm when removing something\n" " -l force line-buffered stdout/stderr\n" " -pN N parallel transactions for for remote\n" @@ -180,7 +181,7 @@ fatal(const char *ctl, ...) #endif " -x use .cpignore as exclusion file\n" " -X file specify exclusion file\n" - " Version 1.14 by Matt Dillon and Dima Ruban\n" + " Version 1.15 by Matt Dillon and Dima Ruban\n" ); exit(0); } else { -- 2.11.4.GIT