This diff should implement --max-size and --min-size almost equivalent to
GNU rsync. I decided to use scan_scaled() instead of building something
new that handles all the extra bits GNU rsync has.
The remote rsync process gets the sizes in bytes so scaling is just a
local issue.

Manpage probably needs more love.
-- 
:wq Claudio

Index: Makefile
===================================================================
RCS file: /cvs/src/usr.bin/rsync/Makefile,v
retrieving revision 1.12
diff -u -p -r1.12 Makefile
--- Makefile    22 Oct 2021 11:10:34 -0000      1.12
+++ Makefile    28 Oct 2021 14:06:07 -0000
@@ -4,8 +4,8 @@ PROG=   openrsync
 SRCS=  blocks.c client.c copy.c downloader.c fargs.c flist.c hash.c ids.c \
        io.c log.c main.c misc.c mkpath.c mktemp.c receiver.c rmatch.c \
        rules.c sender.c server.c session.c socket.c symlinks.c uploader.c
-LDADD+= -lcrypto -lm
-DPADD+= ${LIBCRYPTO} ${LIBM}
+LDADD+= -lcrypto -lm -lutil
+DPADD+= ${LIBCRYPTO} ${LIBM} ${LIBUTIL}
 MAN=   openrsync.1
 
 CFLAGS+= -Wall -Wextra
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.bin/rsync/extern.h,v
retrieving revision 1.42
diff -u -p -r1.42 extern.h
--- extern.h    22 Oct 2021 11:10:34 -0000      1.42
+++ extern.h    28 Oct 2021 13:59:20 -0000
@@ -141,6 +141,8 @@ struct      opts {
        int              numeric_ids;           /* --numeric-ids */
        int              one_file_system;       /* -x */
        int              alt_base_mode;
+       off_t            max_size;              /* --max-size */
+       off_t            min_size;              /* --min-size */
        char            *rsync_path;            /* --rsync-path */
        char            *ssh_prog;              /* --rsh or -e */
        char            *port;                  /* --port */
Index: fargs.c
===================================================================
RCS file: /cvs/src/usr.bin/rsync/fargs.c,v
retrieving revision 1.20
diff -u -p -r1.20 fargs.c
--- fargs.c     22 Oct 2021 11:10:34 -0000      1.20
+++ fargs.c     28 Oct 2021 14:09:23 -0000
@@ -131,6 +131,10 @@ fargs_cmdline(struct sess *sess, const s
        if (!sess->opts->specials && sess->opts->devices)
                /* --devices is sent as -D --no-specials */
                addargs(&args, "--no-specials");
+       if (sess->opts->max_size >= 0)
+               addargs(&args, "--max-size=%lld", sess->opts->max_size);
+       if (sess->opts->min_size >= 0)
+               addargs(&args, "--min-size=%lld", sess->opts->min_size);
 
        /* only add --compare-dest, etc if this is the sender */
        if (sess->opts->alt_base_mode != 0 && 
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/rsync/main.c,v
retrieving revision 1.61
diff -u -p -r1.61 main.c
--- main.c      28 Oct 2021 13:07:43 -0000      1.61
+++ main.c      28 Oct 2021 15:17:39 -0000
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <util.h>
 
 #include "extern.h"
 
@@ -341,7 +342,7 @@ main(int argc, char *argv[])
        pid_t            child;
        int              fds[2], sd = -1, rc, c, st, i, lidx;
        size_t           basedir_cnt = 0;
-       struct sess       sess;
+       struct sess      sess;
        struct fargs    *fargs;
        char            **args;
        const char      *errstr;
@@ -352,6 +353,8 @@ main(int argc, char *argv[])
            NULL) == -1)
                err(ERR_IPC, "pledge");
 
+       opts.max_size = opts.min_size = -1;
+
        while ((c = getopt_long(argc, argv, "Dae:ghlnoprtvxz", lopts, &lidx))
            != -1) {
                switch (c) {
@@ -472,8 +475,12 @@ basedir:
                        opts.basedir[basedir_cnt++] = optarg;
                        break;
                case OP_MAX_SIZE:
+                       if (scan_scaled(optarg, &opts.max_size) == -1)
+                               err(1, "bad max-size");
+                       break;
                case OP_MIN_SIZE:
-                       /* for now simply ignore */
+                       if (scan_scaled(optarg, &opts.min_size) == -1)
+                               err(1, "bad min-size");
                        break;
                case OP_VERSION:
                        fprintf(stderr, "openrsync: protocol version %u\n",
Index: rsync.1
===================================================================
RCS file: /cvs/src/usr.bin/rsync/rsync.1,v
retrieving revision 1.27
diff -u -p -r1.27 rsync.1
--- rsync.1     22 Oct 2021 16:42:28 -0000      1.27
+++ rsync.1     28 Oct 2021 15:29:42 -0000
@@ -31,6 +31,8 @@
 .Op Fl -exclude-from Ns = Ns Ar file
 .Op Fl -include Ar pattern
 .Op Fl -include-from Ns = Ns Ar file
+.Op Fl -max-size Ns = Ns size
+.Op Fl -min-size Ns = Ns size
 .Op Fl -no-motd
 .Op Fl -numeric-ids
 .Op Fl -port Ns = Ns Ar service
@@ -127,6 +129,22 @@ set the numeric group ID to match the so
 Also transfer symbolic links.
 The link is transferred as a standalone file: if the destination does
 not exist, it will be broken.
+.It Fl -max-size Ar size
+Don't transfer any file that is larger than
+.Ar size
+bytes.
+Alternatively
+.Ar size
+may instead use a multiplier, as documented in
+.Xr scan_scaled 3 ,
+to specify the size.
+.It Fl -min-size Ar size
+Don't transfer any file that is smaller than
+.Ar size
+bytes.
+See
+.Fl -max-size
+on the definiton of size.
 .It Fl n , -dry-run
 Do not actually modify the destination.
 Mainly useful in combination with
Index: uploader.c
===================================================================
RCS file: /cvs/src/usr.bin/rsync/uploader.c,v
retrieving revision 1.31
diff -u -p -r1.31 uploader.c
--- uploader.c  24 Oct 2021 21:24:17 -0000      1.31
+++ uploader.c  28 Oct 2021 15:16:59 -0000
@@ -704,6 +704,15 @@ pre_file(const struct upload *p, int *fi
                return 0;
        }
 
+       if (sess->opts->max_size >= 0 && f->st.size > sess->opts->max_size) {
+               WARNX("skipping over max-size file %s", f->path);
+               return 0;
+       }
+       if (sess->opts->min_size >= 0 && f->st.size < sess->opts->min_size) {
+               WARNX("skipping under min-size file %s", f->path);
+               return 0;
+       }
+
        /*
         * For non dry-run cases, we'll write the acknowledgement later
         * in the rsync_uploader() function.

Reply via email to