* 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>
-.\" (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
.Op Fl u
.Op Fl I
.Op Fl f
+.Op Fl F<ssh-arg>
.Op Fl s0
.Op Fl i0
.Op Fl j0
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
int CurParallel;
int MaxParallel = -1;
int HardLinkCount;
+int ssh_argc;
+const char *ssh_argv[16];
int RunningAsUser;
int RunningAsRoot;
const char *UseCpFile;
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;
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) {
}
if (dpath)
RemoveRecur(dpath, ddevNo);
+ st2Valid = 0;
}
/*
}
}
+ /*
+ * 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;
+ }
}
/*
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
+#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
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;
{
int fdin[2];
int fdout[2];
- const char *av[16];
+ const char *av[32];
if (hc == NULL || hc->host == NULL)
return(0);
/*
* Child process
*/
- int n;
+ int n, m;
dup2(fdin[1], 1);
close(fdin[0]);
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";
" -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"
#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 {