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.