Re: Add the -m (--prune-empty-dirs) option to openrsync
Hello again, Job Sorry for the recurring formatting and tab issues. Here's the updated diff. Index: extern.h === RCS file: /cvs/src/usr.bin/rsync/extern.h,v retrieving revision 1.44 diff -u -p -u -p -r1.44 extern.h --- extern.h2 Aug 2022 18:09:20 - 1.44 +++ extern.h22 Feb 2023 17:48:04 - @@ -134,6 +134,7 @@ struct opts { int server;/* --server */ int recursive; /* -r */ int dry_run; /* -n */ + int prune_empty_dirs; /* -m */ int preserve_times;/* -t */ int preserve_perms;/* -p */ int preserve_links;/* -l */ Index: flist.c === RCS file: /cvs/src/usr.bin/rsync/flist.c,v retrieving revision 1.37 diff -u -p -u -p -r1.37 flist.c --- flist.c 26 Dec 2022 19:16:02 - 1.37 +++ flist.c 22 Feb 2023 17:48:05 - @@ -802,10 +802,11 @@ static int flist_gen_dirent(struct sess *sess, char *root, struct flist **fl, size_t *sz, size_t *max) { - char*cargv[2], *cp; - int rc = 0, flag; - FTS *fts; - FTSENT *ent; + char*cargv[2], *prune_cargv[2], *cp; + int rc = 0, flag, empty_chain; + FTS *fts, *prunefts; + FTSENT *ent, *prunent; + struct flist*f; size_t i, flsz = 0, nxdev = 0, stripdir; dev_t *newxdev, *xdev = NULL; @@ -905,6 +906,35 @@ flist_gen_dirent(struct sess *sess, char if (!flist_fts_check(sess, ent)) { errno = 0; continue; + } + + /* +* If -m (prune empty dirs) is enabled, create a new fts +* to independently traverse directories at once and determine +* whether we are dealing with a hierarchy of empty +* directories, if so, skip. +*/ + + if (sess->opts->prune_empty_dirs && ent->fts_info == FTS_D) { + prune_cargv[0] = ent->fts_name; + prune_cargv[1] = NULL; + if ((prunefts = fts_open(prune_cargv, + FTS_PHYSICAL, NULL)) == NULL) { + ERR("fts_open"); + return 0; + } + empty_chain = 1; + while ((prunent = fts_read(prunefts)) != NULL) { + if (prunent->fts_info != FTS_D && + prunent->fts_info != FTS_DP) { + empty_chain = 0; + break; + } + } + if (empty_chain) + continue; + + fts_close(prunefts); } /* We don't allow symlinks without -l. */ Index: main.c === RCS file: /cvs/src/usr.bin/rsync/main.c,v retrieving revision 1.66 diff -u -p -u -p -r1.66 main.c --- main.c 14 Feb 2023 17:15:15 - 1.66 +++ main.c 22 Feb 2023 17:48:05 - @@ -326,6 +326,7 @@ const struct option lopts[] = { { "perms", no_argument,_perms, 1 }, { "no-perms",no_argument,_perms, 0 }, { "port",required_argument, NULL,OP_PORT }, + { "prune-empty-dirs", no_argument, _empty_dirs, 1 }, { "recursive", no_argument,,1 }, { "no-recursive",no_argument,,0 }, { "rsh", required_argument, NULL,'e' }, @@ -362,7 +363,7 @@ main(int argc, char *argv[]) opts.max_size = opts.min_size = -1; - while ((c = getopt_long(argc, argv, "Dae:ghlnoprtvxz", lopts, )) + while ((c = getopt_long(argc, argv, "Dae:ghlmnoprtvxz", lopts, )) != -1) { switch (c) { case 'D': @@ -388,6 +389,9 @@ main(int argc, char *argv[]) case 'l': opts.preserve_links = 1; break; + case 'm': + opts.prune_empty_dirs = 1; + break; case 'n': opts.dry_run = 1; break; @@ -633,7 +637,7 @@ basedir: exit(rc); usage: fprintf(stderr, "usage: %s" - " [-aDglnoprtvx] [-e program] [--address=sourceaddr]\n" + " [-aDglmnoprtvx] [-e program] [--address=sourceaddr]\n"
Re: Add the -m (--prune-empty-dirs) option to openrsync
Hello Job, Sorry for the formatting issues, here's the fixed version, diffed properly via CVS. Index: extern.h === RCS file: /cvs/src/usr.bin/rsync/extern.h,v retrieving revision 1.44 diff -u -p -u -p -r1.44 extern.h --- extern.h 2 Aug 2022 18:09:20 - 1.44 +++ extern.h 22 Feb 2023 16:05:24 - @@ -134,6 +134,7 @@ struct opts { int server; /* --server */ int recursive; /* -r */ int dry_run; /* -n */ + int prune_empty_dirs; /* -m */ int preserve_times; /* -t */ int preserve_perms; /* -p */ int preserve_links; /* -l */ Index: flist.c === RCS file: /cvs/src/usr.bin/rsync/flist.c,v retrieving revision 1.37 diff -u -p -u -p -r1.37 flist.c --- flist.c 26 Dec 2022 19:16:02 - 1.37 +++ flist.c 22 Feb 2023 16:05:24 - @@ -802,10 +802,11 @@ static int flist_gen_dirent(struct sess *sess, char *root, struct flist **fl, size_t *sz, size_t *max) { - char *cargv[2], *cp; - int rc = 0, flag; - FTS *fts; - FTSENT *ent; + char *cargv[2], *prune_cargv[2], *cp; + int rc = 0, flag, empty_chain; + FTS *fts, *prunefts; + FTSENT *ent, *prunent; + struct flist *f; size_t i, flsz = 0, nxdev = 0, stripdir; dev_t *newxdev, *xdev = NULL; @@ -905,6 +906,35 @@ flist_gen_dirent(struct sess *sess, char if (!flist_fts_check(sess, ent)) { errno = 0; continue; + } + + /* + * If -m (prune empty dirs) is enabled, create a new fts + * to independently traverse directories at once and determine + * whether we are dealing with a hierarchy of empty + * directories, if so, skip. + */ + + if (sess->opts->prune_empty_dirs && ent->fts_info == FTS_D) { + prune_cargv[0] = ent->fts_name; + prune_cargv[1] = NULL; + if ((prunefts = fts_open(prune_cargv, + FTS_PHYSICAL, NULL)) == NULL) { + ERR("fts_open"); + return 0; + } + empty_chain = 1; + while ((prunent = fts_read(prunefts)) != NULL) { + if (prunent->fts_info != FTS_D && + prunent->fts_info != FTS_DP) { + empty_chain = 0; + break; + } + } + if (empty_chain) + continue; + + fts_close(prunefts); } /* We don't allow symlinks without -l. */ Index: main.c === RCS file: /cvs/src/usr.bin/rsync/main.c,v retrieving revision 1.66 diff -u -p -u -p -r1.66 main.c --- main.c 14 Feb 2023 17:15:15 - 1.66 +++ main.c 22 Feb 2023 16:05:24 - @@ -326,6 +326,7 @@ const struct option lopts[] = { { "perms", no_argument, _perms, 1 }, { "no-perms", no_argument, _perms, 0 }, { "port", required_argument, NULL, OP_PORT }, + { "prune-empty-dirs", no_argument, _empty_dirs, 1 }, { "recursive", no_argument, , 1 }, { "no-recursive", no_argument, , 0 }, { "rsh", required_argument, NULL, 'e' }, @@ -362,7 +363,7 @@ main(int argc, char *argv[]) opts.max_size = opts.min_size = -1; - while ((c = getopt_long(argc, argv, "Dae:ghlnoprtvxz", lopts, )) + while ((c = getopt_long(argc, argv, "Dae:ghlmnoprtvxz", lopts, )) != -1) { switch (c) { case 'D': @@ -388,6 +389,9 @@ main(int argc, char *argv[]) case 'l': opts.preserve_links = 1; break; + case 'm': + opts.prune_empty_dirs = 1; + break; case 'n': opts.dry_run = 1; break; @@ -633,7 +637,7 @@ basedir: exit(rc); usage: fprintf(stderr, "usage: %s" - " [-aDglnoprtvx] [-e program] [--address=sourceaddr]\n" + " [-aDglmnoprtvx] [-e program] [--address=sourceaddr]\n" "\t[--contimeout=seconds] [--compare-dest=dir] [--del] [--exclude]\n" "\t[--exclude-from=file] [--include] [--include-from=file]\n" "\t[--no-motd] [--numeric-ids] [--port=portnumber]\n" Index: rsync.1 === RCS file: /cvs/src/usr.bin/rsync/rsync.1,v retrieving revision 1.30 diff -u -p -u -p -r1.30 rsync.1 --- rsync.1 2 Aug 2022 18:09:20 - 1.30 +++ rsync.1 22 Feb 2023 16:05:24 - @@ -150,6 +150,8 @@ bytes. See .Fl -max-size on the definition of size. +.It Fl m , -prune-empty-dirs +Prune empty directory chains from the file list. .It Fl n , -dry-run Do not actually modify the destination. Mainly useful in combination with On 2/22/23 10:36, Job Snijders wrote: Dear
Re: Add the -m (--prune-empty-dirs) option to openrsync
Dear Mohamed, On Wed, Feb 22, 2023 at 05:42:10AM +, Mohamed Bukhris wrote: > This patch adds the -m/--prume-empty-dirs option to openrsync > while keeping said feature compatible with rsync > this avoids the 27 -> 31 protocol mismatch error by not sharing the -m option > to remote > This was tested locally (openrsync -> openrsync) and remotely (openrsync -> > rsync) I have a few style remarks, see http://man.openbsd.org/style for full overview of how the code should be formatted to make review & understanding easier within the context of the OpenBSD project. Review is slightly easier if you use 'cvs diff -uNp' to generate the diff. See https://www.openbsd.org/faq/faq5.html#Diff > diff -ura ../origsync/extern.h ./extern.h > --- ../origsync/extern.h 2023-02-21 21:43:18.871417908 +0100 > +++ ./extern.h2023-02-21 18:26:12.176316267 +0100 > @@ -134,6 +134,7 @@ > int server;/* --server */ > int recursive; /* -r */ > int dry_run; /* -n */ > + int prune_empty_dirs; /* -m */ > int preserve_times;/* -t */ > int preserve_perms;/* -p */ > int preserve_links;/* -l */ > diff -ura ../origsync/flist.c ./flist.c > --- ../origsync/flist.c 2023-02-21 21:43:07.778145448 +0100 > +++ ./flist.c 2023-02-22 06:09:51.097975517 +0100 > @@ -907,6 +907,36 @@ > continue; > } > > + /* > + * If -m (prune empty dirs) is enabled, create a new fts > + * to independently traverse directories at once and determine > + * whether we are dealing with a hierarchy of empty > + * directories, if so, skip. > + */ > + > + if (sess->opts->prune_empty_dirs && ent->fts_info == FTS_D){ Add a space between ) and { > + char*prune_cargv[2]; > + prune_cargv[0] = ent->fts_name; > + prune_cargv[1] = NULL; > + FTS *prunefts; Declare FTS *prunefts at the top of flist_gen_dirent() with the rest. > + if ((prunefts = fts_open(prune_cargv, > FTS_PHYSICAL, NULL)) == NULL) { All code should fit in 80 columns. Add a newline after 'prune_cargv,' and indent FTS_PHYSICAL with 4 spaces to make it distinct from the if (). > + ERR("fts_open"); > + return 0; > + } > + FTSENT *prunent; > + int empty_chain = 1; Please initiatize variables at the top of flist_gen_dirent(). > + while ((prunent = fts_read(prunefts)) != NULL) { > + if (prunent->fts_info != FTS_D && > prunent->fts_info != FTS_DP){ Above line is too long. Add a space between ) and { > + empty_chain = 0; > + break; > + } > + } > + if (empty_chain){ > + continue; > + } Add a space between ) and {, and as 'continue' is the only statement inside this if-block, you can write it like so: if (empty_chain) continue; > + fts_close(prunefts); > + } > + > /* We don't allow symlinks without -l. */ > > assert(ent->fts_statp != NULL); > diff -ura ../origsync/main.c ./main.c > --- ../origsync/main.c2023-02-21 21:43:10.861461862 +0100 > +++ ./main.c 2023-02-22 05:21:15.047310523 +0100 > @@ -340,6 +340,7 @@ > { "verbose", no_argument,, 1 }, > { "no-verbose", no_argument,, 0 }, > { "version", no_argument,NULL, OP_VERSION }, > + { "prune-empty-dirs", no_argument, _empty_dirs, 1 }, Align it using spaces like the other lines inside struct option lopts[] Use semi-alphabetical ordering, move the line to under "port". > { NULL, 0, NULL, 0 } > }; > > @@ -362,7 +363,7 @@ > > opts.max_size = opts.min_size = -1; > > - while ((c = getopt_long(argc, argv, "Dae:ghlnoprtvxz", lopts, )) > + while ((c = getopt_long(argc, argv, "Dae:ghlnoprtvxzm", lopts, )) The optstring argument should be ordered, add 'm' after l' instead. > != -1) { > switch (c) { > case 'D': > @@ -382,6 +383,9 @@ > case 'e': > opts.ssh_prog = optarg; > break; > + case 'm': > + opts.prune_empty_dirs = 1; > + break; > case 'g': > opts.preserve_gids = 1; >