Add --one-file-system, which prevents openrsync to cross filesystem
boundaries. Option and behaviour is the same as GPL rsync.
OK?
diff --git usr.bin/rsync/extern.h usr.bin/rsync/extern.h
index 12aceae566c..602cd24cede 100644
--- usr.bin/rsync/extern.h
+++ usr.bin/rsync/extern.h
@@ -117,6 +117,7 @@ struct opts {
int devices; /* --devices */
int specials; /* --specials */
int numeric_ids; /* --numeric-ids */
+ int one_file_system; /* --one-file-system or -x */
char *rsync_path; /* --rsync-path */
char *ssh_prog; /* --rsh or -e */
char *port; /* --port */
diff --git usr.bin/rsync/flist.c usr.bin/rsync/flist.c
index b39599583e3..7f18966d85d 100644
--- usr.bin/rsync/flist.c
+++ usr.bin/rsync/flist.c
@@ -804,7 +804,7 @@ flist_gen_dirent(struct sess *sess, char *root, struct
flist **fl, size_t *sz,
size_t *max)
{
char *cargv[2], *cp;
- int rc = 0;
+ int rc = 0, xdev = 0;
FTS *fts;
FTSENT *ent;
struct flist *f;
@@ -890,9 +890,15 @@ flist_gen_dirent(struct sess *sess, char *root, struct
flist **fl, size_t *sz,
* files and directory components, so use fts(3).
* Copying the information file-by-file into the flstat.
* We'll make sense of it in flist_send.
+ * If one-file-system is used, prevent fts(3) from descending
+ * into directories that have a different device number than
+ * the file from which the descent began.
*/
- if ((fts = fts_open(cargv, FTS_PHYSICAL, NULL)) == NULL) {
+ if (sess->opts->one_file_system)
+ xdev = FTS_XDEV;
+
+ if ((fts = fts_open(cargv, FTS_PHYSICAL | xdev, NULL)) == NULL) {
ERR(sess, "fts_open");
return 0;
}
@@ -1129,7 +1135,7 @@ flist_gen_dels(struct sess *sess, const char *root,
struct flist **fl,
size_t *sz, const struct flist *wfl, size_t wflsz)
{
char **cargv = NULL;
- int rc = 0, c;
+ int rc = 0, c, xdev = 0;
FTS *fts = NULL;
FTSENT *ent;
struct flist *f;
@@ -1235,9 +1241,15 @@ flist_gen_dels(struct sess *sess, const char *root,
struct flist **fl,
* Now we're going to try to descend into all of the top-level
* directories stipulated by the file list.
* If the directories don't exist, it's ok.
+ * If one-file-system is used, prevent fts(3) from descending
+ * into directories that have a different device number than
+ * the file from which the descent began.
*/
- if ((fts = fts_open(cargv, FTS_PHYSICAL, NULL)) == NULL) {
+ if (sess->opts->one_file_system)
+ xdev = FTS_XDEV;
+
+ if ((fts = fts_open(cargv, FTS_PHYSICAL | xdev, NULL)) == NULL) {
ERR(sess, "fts_open");
goto out;
}
diff --git usr.bin/rsync/main.c usr.bin/rsync/main.c
index dd598d93eb2..3dbf6dd6028 100644
--- usr.bin/rsync/main.c
+++ usr.bin/rsync/main.c
@@ -305,6 +305,7 @@ main(int argc, char *argv[])
{ "no-times", no_argument, &opts.preserve_times, 0 },
{ "verbose", no_argument, &opts.verbose, 1 },
{ "no-verbose", no_argument, &opts.verbose, 0 },
+ { "one-file-system", no_argument, NULL, 'x' },
{ NULL, 0, NULL, 0 }};
/* Global pledge. */
@@ -315,7 +316,7 @@ main(int argc, char *argv[])
memset(&opts, 0, sizeof(struct opts));
- while ((c = getopt_long(argc, argv, "Dae:ghlnoprtvz", lopts, NULL))
+ while ((c = getopt_long(argc, argv, "Dae:ghlnoprtvxz", lopts, NULL))
!= -1) {
switch (c) {
case 'D':
@@ -359,6 +360,9 @@ main(int argc, char *argv[])
case 'v':
opts.verbose++;
break;
+ case 'x':
+ opts.one_file_system = 1;
+ break;
case 'z':
fprintf(stderr, "%s: -z not supported yet\n",
getprogname());
break;
diff --git usr.bin/rsync/rsync.1 usr.bin/rsync/rsync.1
index c16168fff8f..911c848da7e 100644
--- usr.bin/rsync/rsync.1
+++ usr.bin/rsync/rsync.1
@@ -141,6 +141,8 @@ Increase verbosity.
Specify once for files being transferred, twice for specific status,
thrice for per-file transfer information, and four times for per-file
breakdowns.
+.It Fl x , -one-file-system
+Do not cross filesystem boundaries.
.It Fl -version
Print version and exit.
.El