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