cpdup - Add -F<ssh-opt>, add code to remove need for FreeBSD ports patch
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 24 Nov 2009 19:07:18 +0000 (11:07 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 24 Nov 2009 19:07:18 +0000 (11:07 -0800)
* Add -F<ssh-opt>, allow arbitrary options to be passed to ssh.

* Ignore UFS2 snapshots (FreeBSD)

* Add missing #include (FreeBSD)

Submitted-by: Oliver Fromme <olli@fromme.com>
bin/cpdup/cpdup.1
bin/cpdup/cpdup.c
bin/cpdup/cpdup.h
bin/cpdup/hclink.c
bin/cpdup/misc.c

index 4d4d25b..73f7a50 100644 (file)
@@ -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<ssh-arg>
 .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<ssh-arg>
+Pass <ssh-arg> 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
index 0441ef5..144856b 100644 (file)
@@ -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;
+                   }
            }
 
            /*
index 4017008..61ef9b7 100644 (file)
@@ -14,6 +14,7 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
@@ -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;
index be0769c..45e56e4 100644 (file)
@@ -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";
index a3e243e..098f051 100644 (file)
@@ -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<ssh_opt> Add <ssh_opt> 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 {