Implement --size-only and --ignore-times
authorclaudio <claudio@openbsd.org>
Fri, 28 Apr 2023 10:24:38 +0000 (10:24 +0000)
committerclaudio <claudio@openbsd.org>
Fri, 28 Apr 2023 10:24:38 +0000 (10:24 +0000)
Flags are passed to the remote system but --size-only is only set
if local system is sender since this is the behaviour of rsync.
Initial diff from Martin Cracauer but mostly reimplemented and extended
by myself.
OK kn@

usr.bin/rsync/extern.h
usr.bin/rsync/fargs.c
usr.bin/rsync/main.c
usr.bin/rsync/rsync.1
usr.bin/rsync/uploader.c

index 7de0211..858c002 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: extern.h,v 1.44 2022/08/02 18:09:20 job Exp $ */
+/*     $OpenBSD: extern.h,v 1.45 2023/04/28 10:24:38 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -145,6 +145,8 @@ struct      opts {
        int              no_motd;               /* --no-motd */
        int              numeric_ids;           /* --numeric-ids */
        int              one_file_system;       /* -x */
+       int              ignore_times;          /* -I */
+       int              size_only;             /* --size-only */
        int              alt_base_mode;
        off_t            max_size;              /* --max-size */
        off_t            min_size;              /* --min-size */
index 7ccb5bf..826260f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: fargs.c,v 1.23 2022/01/12 22:52:40 tb Exp $ */
+/*     $OpenBSD: fargs.c,v 1.24 2023/04/28 10:24:38 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -114,6 +114,8 @@ fargs_cmdline(struct sess *sess, const struct fargs *f, size_t *skip)
                addargs(&args, "-r");
        if (sess->opts->preserve_times)
                addargs(&args, "-t");
+       if (sess->opts->ignore_times)
+               addargs(&args, "-I");
        if (verbose > 3)
                addargs(&args, "-v");
        if (verbose > 2)
@@ -136,15 +138,20 @@ fargs_cmdline(struct sess *sess, const struct fargs *f, size_t *skip)
        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 &&
-           f->mode == FARGS_SENDER) {
-               for (j = 0; j < MAX_BASEDIR; j++) {
-                       if (sess->opts->basedir[j] == NULL)
-                               break;
-                       addargs(&args, "%s=%s",
-                           alt_base_mode(sess->opts->alt_base_mode),
-                           sess->opts->basedir[j]);
+       /* extra options for the receiver (local is sender) */
+       if (f->mode == FARGS_SENDER) {
+               if (sess->opts->size_only)
+                       addargs(&args, "--size-only");
+
+               /* only add --compare-dest, etc if this is the sender */
+               if (sess->opts->alt_base_mode != 0) {
+                       for (j = 0; j < MAX_BASEDIR; j++) {
+                               if (sess->opts->basedir[j] == NULL)
+                                       break;
+                               addargs(&args, "%s=%s",
+                                   alt_base_mode(sess->opts->alt_base_mode),
+                                   sess->opts->basedir[j]);
+                       }
                }
        }
 
index 60abf27..30231f3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.c,v 1.67 2023/04/27 16:28:18 claudio Exp $ */
+/*     $OpenBSD: main.c,v 1.68 2023/04/28 10:24:38 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -312,6 +312,7 @@ const struct option  lopts[] = {
     { "group",         no_argument,    &opts.preserve_gids,    1 },
     { "no-group",      no_argument,    &opts.preserve_gids,    0 },
     { "help",          no_argument,    NULL,                   'h' },
+    { "ignore-times",  no_argument,    NULL,                   'I' },
     { "include",       required_argument, NULL,                OP_INCLUDE },
     { "include-from",  required_argument, NULL,                OP_INCLUDE_FROM },
     { "links",         no_argument,    &opts.preserve_links,   1 },
@@ -331,6 +332,7 @@ const struct option  lopts[] = {
     { "rsync-path",    required_argument, NULL,                OP_RSYNCPATH },
     { "sender",                no_argument,    &opts.sender,           1 },
     { "server",                no_argument,    &opts.server,           1 },
+    { "size-only",     no_argument,    &opts.size_only,        1 },
     { "specials",      no_argument,    &opts.specials,         1 },
     { "no-specials",   no_argument,    &opts.specials,         0 },
     { "timeout",       required_argument, NULL,                OP_TIMEOUT },
@@ -361,7 +363,7 @@ main(int argc, char *argv[])
 
        opts.max_size = opts.min_size = -1;
 
-       while ((c = getopt_long(argc, argv, "aDe:ghlnoprtVvxz", lopts, &lidx))
+       while ((c = getopt_long(argc, argv, "aDe:ghIlnoprtVvxz", lopts, &lidx))
            != -1) {
                switch (c) {
                case 'D':
@@ -384,6 +386,9 @@ main(int argc, char *argv[])
                case 'g':
                        opts.preserve_gids = 1;
                        break;
+               case 'I':
+                       opts.ignore_times = 1;
+                       break;
                case 'l':
                        opts.preserve_links = 1;
                        break;
@@ -632,11 +637,11 @@ basedir:
        exit(rc);
 usage:
        fprintf(stderr, "usage: %s"
-           " [-aDglnoprtVvx] [-e program] [--address=sourceaddr]\n"
+           " [-aDgIlnoprtVvx] [-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"
-           "\t[--rsync-path=program] [--timeout=seconds]\n"
+           "\t[--rsync-path=program] [--size-only] [--timeout=seconds]\n"
            "\tsource ... directory\n",
            getprogname());
        exit(ERR_SYNTAX);
index 9427249..bc8b536 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: rsync.1,v 1.32 2023/04/27 17:18:40 jmc Exp $
+.\"    $OpenBSD: rsync.1,v 1.33 2023/04/28 10:24:38 claudio Exp $
 .\"
 .\" Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: April 27 2023 $
+.Dd $Mdocdate: April 28 2023 $
 .Dt OPENRSYNC 1
 .Os
 .Sh NAME
@@ -22,7 +22,7 @@
 .Nd synchronise local and remote files
 .Sh SYNOPSIS
 .Nm openrsync
-.Op Fl aDglnoprtVvx
+.Op Fl aDgIlnoprtVvx
 .Op Fl e Ar program
 .Op Fl -address Ns = Ns Ar sourceaddr
 .Op Fl -compare-dest Ns = Ns Ar directory
@@ -38,6 +38,7 @@
 .Op Fl -numeric-ids
 .Op Fl -port Ns = Ns Ar service
 .Op Fl -rsync-path Ns = Ns Ar program
+.Op Fl -size-only
 .Op Fl -timeout Ns = Ns Ar seconds
 .Ar source ...
 .Ar directory
@@ -93,6 +94,9 @@ not found in
 directories.
 Only applicable with
 .Fl r .
+.It Fl e Ar program , Fl -rsh Ns = Ns Ar program
+Specify alternative communication program, defaults to
+.Xr ssh 1 .
 .It Fl -exclude Ar pattern
 Exclude files matching
 .Em pattern .
@@ -103,21 +107,8 @@ and
 .Em rules
 from
 .Em file .
-.It Fl -include Ar pattern
-Include files matching
-.Em pattern .
-.It Fl -include-from Ns = Ns Ar file
-Load
-.Em patterns
-and
-.Em rules
-from
-.Em file .
 .It Fl -devices
 Also transfer device files.
-.It Fl e Ar program , Fl -rsh Ns = Ns Ar program
-Specify alternative communication program, defaults to
-.Xr ssh 1 .
 .It Fl g , -group
 Set the group name to match the source.
 For example, group
@@ -129,6 +120,18 @@ If
 .Fl -numeric-ids
 is also given or if the remote group name is unknown on the local machine,
 set the numeric group ID to match the source instead.
+.It Fl I , -ignore-times
+Do not skip based on file size and modification time.
+.It Fl -include Ar pattern
+Include files matching
+.Em pattern .
+.It Fl -include-from Ns = Ns Ar file
+Load
+.Em patterns
+and
+.Em rules
+from
+.Em file .
 .It Fl l , -links
 Also transfer symbolic links.
 The link is transferred as a standalone file: if the destination does
@@ -200,6 +203,8 @@ Run
 .Ar program
 on the remote host instead of the default
 .Pa rsync .
+.It Fl -size-only
+Skip files based only on size, don't check timestamp.
 .It Fl -specials
 Also transfer fifo and unix domain socket files.
 .It Fl -timeout Ns = Ns Ar seconds
index 678b6c9..ddc54c8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uploader.c,v 1.33 2021/11/03 14:42:12 deraadt Exp $ */
+/*     $OpenBSD: uploader.c,v 1.34 2023/04/28 10:24:39 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2019 Florian Obser <florian@openbsd.org>
@@ -652,7 +652,8 @@ post_dir(struct sess *sess, const struct upload *u, size_t idx)
  * The stat pointer st is only valid for 0, 1, and 2 returns.
  */
 static int
-check_file(int rootfd, const struct flist *f, struct stat *st)
+check_file(int rootfd, const struct flist *f, struct stat *st,
+    struct sess *sess)
 {
        if (fstatat(rootfd, f->path, st, AT_SYMLINK_NOFOLLOW) == -1) {
                if (errno == ENOENT)
@@ -666,9 +667,16 @@ check_file(int rootfd, const struct flist *f, struct stat *st)
        if (!S_ISREG(st->st_mode))
                return 2;
 
+       /* TODO: add support for --checksum */
+
+       /* if ignore_times is on file needs attention */
+       if (sess->opts->ignore_times)
+               return 2;
+
        /* quick check if file is the same */
-       /* TODO: add support for --checksum, --size-only and --ignore-times */
        if (st->st_size == f->st.size) {
+               if (sess->opts->size_only)
+                       return 0;
                if (st->st_mtime == f->st.mtime)
                        return 0;
                return 1;
@@ -721,7 +729,7 @@ pre_file(const struct upload *p, int *filefd, off_t *size,
        *size = 0;
        *filefd = -1;
 
-       rc = check_file(p->rootfd, f, &st);
+       rc = check_file(p->rootfd, f, &st, sess);
        if (rc == -1)
                return -1;
        if (rc == 2 && !S_ISREG(st.st_mode)) {
@@ -748,7 +756,7 @@ pre_file(const struct upload *p, int *filefd, off_t *size,
                dfd = openat(p->rootfd, root, O_RDONLY | O_DIRECTORY);
                if (dfd == -1)
                        err(ERR_FILE_IO, "%s: openat", root);
-               x = check_file(dfd, f, &st);
+               x = check_file(dfd, f, &st, sess);
                /* found a match */
                if (x == 0) {
                        if (rc >= 0) {