[BACK]Return to main.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / rsync

Diff for /src/usr.bin/rsync/main.c between version 1.53 and 1.53.2.1

version 1.53, 2021/03/31 19:45:16 version 1.53.2.1, 2021/11/09 13:41:24
Line 26 
Line 26 
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
   #include <util.h>
   
 #include "extern.h"  #include "extern.h"
   
Line 83 
Line 84 
         /* Allocations. */          /* Allocations. */
   
         if ((f = calloc(1, sizeof(struct fargs))) == NULL)          if ((f = calloc(1, sizeof(struct fargs))) == NULL)
                 err(1, "calloc");                  err(ERR_NOMEM, NULL);
   
         f->sourcesz = argc - 1;          f->sourcesz = argc - 1;
         if ((f->sources = calloc(f->sourcesz, sizeof(char *))) == NULL)          if ((f->sources = calloc(f->sourcesz, sizeof(char *))) == NULL)
                 err(1, "calloc");                  err(ERR_NOMEM, NULL);
   
         for (i = 0; i < argc - 1; i++)          for (i = 0; i < argc - 1; i++)
                 if ((f->sources[i] = strdup(argv[i])) == NULL)                  if ((f->sources[i] = strdup(argv[i])) == NULL)
                         err(1, "strdup");                          err(ERR_NOMEM, NULL);
   
         if ((f->sink = strdup(argv[i])) == NULL)          if ((f->sink = strdup(argv[i])) == NULL)
                 err(1, "strdup");                  err(ERR_NOMEM, NULL);
   
         /*          /*
          * Test files for its locality.           * Test files for its locality.
Line 109 
Line 110 
         if (fargs_is_remote(f->sink)) {          if (fargs_is_remote(f->sink)) {
                 f->mode = FARGS_SENDER;                  f->mode = FARGS_SENDER;
                 if ((f->host = strdup(f->sink)) == NULL)                  if ((f->host = strdup(f->sink)) == NULL)
                         err(1, "strdup");                          err(ERR_NOMEM, NULL);
         }          }
   
         if (fargs_is_remote(f->sources[0])) {          if (fargs_is_remote(f->sources[0])) {
                 if (f->host != NULL)                  if (f->host != NULL)
                         errx(1, "both source and destination cannot be remote files");                          errx(ERR_SYNTAX, "both source and destination "
                               "cannot be remote files");
                 f->mode = FARGS_RECEIVER;                  f->mode = FARGS_RECEIVER;
                 if ((f->host = strdup(f->sources[0])) == NULL)                  if ((f->host = strdup(f->sources[0])) == NULL)
                         err(1, "strdup");                          err(ERR_NOMEM, NULL);
         }          }
   
         if (f->host != NULL) {          if (f->host != NULL) {
Line 127 
Line 129 
                         len = strlen(f->host) - 8 + 1;                          len = strlen(f->host) - 8 + 1;
                         memmove(f->host, f->host + 8, len);                          memmove(f->host, f->host + 8, len);
                         if ((cp = strchr(f->host, '/')) == NULL)                          if ((cp = strchr(f->host, '/')) == NULL)
                                 errx(1, "rsync protocol requires a module name");                                  errx(ERR_SYNTAX,
                                       "rsync protocol requires a module name");
                         *cp++ = '\0';                          *cp++ = '\0';
                         f->module = cp;                          f->module = cp;
                         if ((cp = strchr(f->module, '/')) != NULL)                          if ((cp = strchr(f->module, '/')) != NULL)
Line 152 
Line 155 
                         }                          }
                 }                  }
                 if ((len = strlen(f->host)) == 0)                  if ((len = strlen(f->host)) == 0)
                         errx(1, "empty remote host");                          errx(ERR_SYNTAX, "empty remote host");
                 if (f->remote && strlen(f->module) == 0)                  if (f->remote && strlen(f->module) == 0)
                         errx(1, "empty remote module");                          errx(ERR_SYNTAX, "empty remote module");
         }          }
   
         /* Make sure we have the same "hostspec" for all files. */          /* Make sure we have the same "hostspec" for all files. */
Line 164 
Line 167 
                         for (i = 0; i < f->sourcesz; i++) {                          for (i = 0; i < f->sourcesz; i++) {
                                 if (!fargs_is_remote(f->sources[i]))                                  if (!fargs_is_remote(f->sources[i]))
                                         continue;                                          continue;
                                 errx(1,                                  errx(ERR_SYNTAX,
                                     "remote file in list of local sources: %s",                                      "remote file in list of local sources: %s",
                                     f->sources[i]);                                      f->sources[i]);
                         }                          }
Line 174 
Line 177 
                                     !fargs_is_daemon(f->sources[i]))                                      !fargs_is_daemon(f->sources[i]))
                                         continue;                                          continue;
                                 if (fargs_is_daemon(f->sources[i]))                                  if (fargs_is_daemon(f->sources[i]))
                                         errx(1, "remote daemon in list of "                                          errx(ERR_SYNTAX,
                                             "remote sources: %s",                                              "remote daemon in list of remote "
                                             f->sources[i]);                                              "sources: %s", f->sources[i]);
                                 errx(1, "local file in list of remote sources: %s",                                  errx(ERR_SYNTAX, "local file in list of "
                                     f->sources[i]);                                      "remote sources: %s", f->sources[i]);
                         }                          }
         } else {          } else {
                 if (f->mode != FARGS_RECEIVER)                  if (f->mode != FARGS_RECEIVER)
                         errx(1, "sender mode for remote "                          errx(ERR_SYNTAX, "sender mode for remote "
                                 "daemon receivers not yet supported");                                  "daemon receivers not yet supported");
                 for (i = 0; i < f->sourcesz; i++) {                  for (i = 0; i < f->sourcesz; i++) {
                         if (fargs_is_daemon(f->sources[i]))                          if (fargs_is_daemon(f->sources[i]))
                                 continue;                                  continue;
                         errx(1, "non-remote daemon file "                          errx(ERR_SYNTAX, "non-remote daemon file "
                                 "in list of remote daemon sources: "                                  "in list of remote daemon sources: "
                                 "%s", f->sources[i]);                                  "%s", f->sources[i]);
                 }                  }
Line 233 
Line 236 
                                 *ccp = '\0';                                  *ccp = '\0';
                         if (strncmp(cp, f->host, len) ||                          if (strncmp(cp, f->host, len) ||
                             (cp[len] != '/' && cp[len] != '\0'))                              (cp[len] != '/' && cp[len] != '\0'))
                                 errx(1, "different remote host: %s",                                  errx(ERR_SYNTAX, "different remote host: %s",
                                     f->sources[i]);                                      f->sources[i]);
                         memmove(f->sources[i],                          memmove(f->sources[i],
                                 f->sources[i] + len + 8 + 1,                                  f->sources[i] + len + 8 + 1,
Line 246 
Line 249 
                         /* host::path */                          /* host::path */
                         if (strncmp(cp, f->host, len) ||                          if (strncmp(cp, f->host, len) ||
                             (cp[len] != ':' && cp[len] != '\0'))                              (cp[len] != ':' && cp[len] != '\0'))
                                 errx(1, "different remote host: %s",                                  errx(ERR_SYNTAX, "different remote host: %s",
                                     f->sources[i]);                                      f->sources[i]);
                         memmove(f->sources[i], f->sources[i] + len + 2,                          memmove(f->sources[i], f->sources[i] + len + 2,
                             j - len - 1);                              j - len - 1);
Line 257 
Line 260 
                         /* host:path */                          /* host:path */
                         if (strncmp(cp, f->host, len) ||                          if (strncmp(cp, f->host, len) ||
                             (cp[len] != ':' && cp[len] != '\0'))                              (cp[len] != ':' && cp[len] != '\0'))
                                 errx(1, "different remote host: %s",                                  errx(ERR_SYNTAX, "different remote host: %s",
                                     f->sources[i]);                                      f->sources[i]);
                         memmove(f->sources[i],                          memmove(f->sources[i],
                                 f->sources[i] + len + 1, j - len);                                  f->sources[i] + len + 1, j - len);
Line 267 
Line 270 
         return f;          return f;
 }  }
   
   static struct opts       opts;
   
   #define OP_ADDRESS      1000
   #define OP_PORT         1001
   #define OP_RSYNCPATH    1002
   #define OP_TIMEOUT      1003
   #define OP_VERSION      1004
   #define OP_EXCLUDE      1005
   #define OP_INCLUDE      1006
   #define OP_EXCLUDE_FROM 1007
   #define OP_INCLUDE_FROM 1008
   #define OP_COMP_DEST    1009
   #define OP_COPY_DEST    1010
   #define OP_LINK_DEST    1011
   #define OP_MAX_SIZE     1012
   #define OP_MIN_SIZE     1013
   
   const struct option      lopts[] = {
       { "address",        required_argument, NULL,                OP_ADDRESS },
       { "archive",        no_argument,    NULL,                   'a' },
       { "compare-dest",   required_argument, NULL,                OP_COMP_DEST },
   #if 0
       { "copy-dest",      required_argument, NULL,                OP_COPY_DEST },
       { "link-dest",      required_argument, NULL,                OP_LINK_DEST },
   #endif
       { "compress",       no_argument,    NULL,                   'z' },
       { "del",            no_argument,    &opts.del,              1 },
       { "delete",         no_argument,    &opts.del,              1 },
       { "devices",        no_argument,    &opts.devices,          1 },
       { "no-devices",     no_argument,    &opts.devices,          0 },
       { "dry-run",        no_argument,    &opts.dry_run,          1 },
       { "exclude",        required_argument, NULL,                OP_EXCLUDE },
       { "exclude-from",   required_argument, NULL,                OP_EXCLUDE_FROM },
       { "group",          no_argument,    &opts.preserve_gids,    1 },
       { "no-group",       no_argument,    &opts.preserve_gids,    0 },
       { "help",           no_argument,    NULL,                   'h' },
       { "include",        required_argument, NULL,                OP_INCLUDE },
       { "include-from",   required_argument, NULL,                OP_INCLUDE_FROM },
       { "links",          no_argument,    &opts.preserve_links,   1 },
       { "max-size",       required_argument, NULL,                OP_MAX_SIZE },
       { "min-size",       required_argument, NULL,                OP_MIN_SIZE },
       { "no-links",       no_argument,    &opts.preserve_links,   0 },
       { "no-motd",        no_argument,    &opts.no_motd,          1 },
       { "numeric-ids",    no_argument,    &opts.numeric_ids,      1 },
       { "owner",          no_argument,    &opts.preserve_uids,    1 },
       { "no-owner",       no_argument,    &opts.preserve_uids,    0 },
       { "perms",          no_argument,    &opts.preserve_perms,   1 },
       { "no-perms",       no_argument,    &opts.preserve_perms,   0 },
       { "port",           required_argument, NULL,                OP_PORT },
       { "recursive",      no_argument,    &opts.recursive,        1 },
       { "no-recursive",   no_argument,    &opts.recursive,        0 },
       { "rsh",            required_argument, NULL,                'e' },
       { "rsync-path",     required_argument, NULL,                OP_RSYNCPATH },
       { "sender",         no_argument,    &opts.sender,           1 },
       { "server",         no_argument,    &opts.server,           1 },
       { "specials",       no_argument,    &opts.specials,         1 },
       { "no-specials",    no_argument,    &opts.specials,         0 },
       { "timeout",        required_argument, NULL,                OP_TIMEOUT },
       { "times",          no_argument,    &opts.preserve_times,   1 },
       { "no-times",       no_argument,    &opts.preserve_times,   0 },
       { "verbose",        no_argument,    &verbose,               1 },
       { "no-verbose",     no_argument,    &verbose,               0 },
       { "version",        no_argument,    NULL,                   OP_VERSION },
       { NULL,             0,              NULL,                   0 }
   };
   
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
         struct opts      opts;  
         pid_t            child;          pid_t            child;
         int              fds[2], sd = -1, rc, c, st, i;          int              fds[2], sd = -1, rc, c, st, i, lidx;
         struct sess       sess;          size_t           basedir_cnt = 0;
           struct sess      sess;
         struct fargs    *fargs;          struct fargs    *fargs;
         char            **args;          char            **args;
         const char      *errstr;          const char      *errstr;
         const struct option      lopts[] = {  
                 { "port",       required_argument, NULL,                3 },  
                 { "rsh",        required_argument, NULL,                'e' },  
                 { "rsync-path", required_argument, NULL,                1 },  
                 { "sender",     no_argument,    &opts.sender,           1 },  
                 { "server",     no_argument,    &opts.server,           1 },  
                 { "dry-run",    no_argument,    &opts.dry_run,          1 },  
                 { "version",    no_argument,    NULL,                   2 },  
                 { "archive",    no_argument,    NULL,                   'a' },  
                 { "help",       no_argument,    NULL,                   'h' },  
                 { "compress",   no_argument,    NULL,                   'z' },  
                 { "del",        no_argument,    &opts.del,              1 },  
                 { "delete",     no_argument,    &opts.del,              1 },  
                 { "devices",    no_argument,    &opts.devices,          1 },  
                 { "no-devices", no_argument,    &opts.devices,          0 },  
                 { "group",      no_argument,    &opts.preserve_gids,    1 },  
                 { "no-group",   no_argument,    &opts.preserve_gids,    0 },  
                 { "links",      no_argument,    &opts.preserve_links,   1 },  
                 { "no-links",   no_argument,    &opts.preserve_links,   0 },  
                 { "owner",      no_argument,    &opts.preserve_uids,    1 },  
                 { "no-owner",   no_argument,    &opts.preserve_uids,    0 },  
                 { "perms",      no_argument,    &opts.preserve_perms,   1 },  
                 { "no-perms",   no_argument,    &opts.preserve_perms,   0 },  
                 { "numeric-ids", no_argument,   &opts.numeric_ids,      1 },  
                 { "recursive",  no_argument,    &opts.recursive,        1 },  
                 { "no-recursive", no_argument,  &opts.recursive,        0 },  
                 { "specials",   no_argument,    &opts.specials,         1 },  
                 { "no-specials", no_argument,   &opts.specials,         0 },  
                 { "timeout",    required_argument, NULL,                5 },  
                 { "times",      no_argument,    &opts.preserve_times,   1 },  
                 { "no-times",   no_argument,    &opts.preserve_times,   0 },  
                 { "verbose",    no_argument,    &verbose,               1 },  
                 { "no-verbose", no_argument,    &verbose,               0 },  
                 { "address",    required_argument, NULL,                4 },  
                 { "no-motd",    no_argument,    NULL,                   6 },  
                 { NULL,         0,              NULL,                   0 }};  
   
         /* Global pledge. */          /* Global pledge. */
   
         if (pledge("stdio unix rpath wpath cpath dpath inet fattr chown dns getpw proc exec unveil",          if (pledge("stdio unix rpath wpath cpath dpath inet fattr chown dns getpw proc exec unveil",
             NULL) == -1)              NULL) == -1)
                 err(1, "pledge");                  err(ERR_IPC, "pledge");
   
         memset(&opts, 0, sizeof(struct opts));          opts.max_size = opts.min_size = -1;
   
         while ((c = getopt_long(argc, argv, "Dae:ghlnoprtvxz", lopts, NULL))          while ((c = getopt_long(argc, argv, "Dae:ghlnoprtvxz", lopts, &lidx))
             != -1) {              != -1) {
                 switch (c) {                  switch (c) {
                 case 'D':                  case 'D':
Line 375 
Line 408 
                 case 0:                  case 0:
                         /* Non-NULL flag values (e.g., --sender). */                          /* Non-NULL flag values (e.g., --sender). */
                         break;                          break;
                 case 1:                  case OP_ADDRESS:
                         opts.rsync_path = optarg;                          opts.address = optarg;
                         break;                          break;
                 case 2:                  case OP_PORT:
                         fprintf(stderr, "openrsync: protocol version %u\n",  
                             RSYNC_PROTOCOL);  
                         exit(0);  
                 case 3:  
                         opts.port = optarg;                          opts.port = optarg;
                         break;                          break;
                 case 4:                  case OP_RSYNCPATH:
                         opts.address = optarg;                          opts.rsync_path = optarg;
                         break;                          break;
                 case 5:                  case OP_TIMEOUT:
                         poll_timeout = strtonum(optarg, 0, 60*60, &errstr);                          poll_timeout = strtonum(optarg, 0, 60*60, &errstr);
                         if (errstr != NULL)                          if (errstr != NULL)
                                 errx(1, "timeout is %s: %s", errstr, optarg);                                  errx(ERR_SYNTAX, "timeout is %s: %s",
                                       errstr, optarg);
                         break;                          break;
                 case 6:                  case OP_EXCLUDE:
                         opts.no_motd = 1;                          if (parse_rule(optarg, RULE_EXCLUDE) == -1)
                                   errx(ERR_SYNTAX, "syntax error in exclude: %s",
                                       optarg);
                         break;                          break;
                   case OP_INCLUDE:
                           if (parse_rule(optarg, RULE_INCLUDE) == -1)
                                   errx(ERR_SYNTAX, "syntax error in include: %s",
                                       optarg);
                           break;
                   case OP_EXCLUDE_FROM:
                           parse_file(optarg, RULE_EXCLUDE);
                           break;
                   case OP_INCLUDE_FROM:
                           parse_file(optarg, RULE_INCLUDE);
                           break;
                   case OP_COMP_DEST:
                           if (opts.alt_base_mode !=0 &&
                               opts.alt_base_mode != BASE_MODE_COMPARE) {
                                   errx(1, "option --%s conflicts with %s",
                                       lopts[lidx].name,
                                       alt_base_mode(opts.alt_base_mode));
                           }
                           opts.alt_base_mode = BASE_MODE_COMPARE;
   #if 0
                           goto basedir;
                   case OP_COPY_DEST:
                           if (opts.alt_base_mode !=0 &&
                               opts.alt_base_mode != BASE_MODE_COPY) {
                                   errx(1, "option --%s conflicts with %s",
                                       lopts[lidx].name,
                                       alt_base_mode(opts.alt_base_mode));
                           }
                           opts.alt_base_mode = BASE_MODE_COPY;
                           goto basedir;
                   case OP_LINK_DEST:
                           if (opts.alt_base_mode !=0 &&
                               opts.alt_base_mode != BASE_MODE_LINK) {
                                   errx(1, "option --%s conflicts with %s",
                                       lopts[lidx].name,
                                       alt_base_mode(opts.alt_base_mode));
                           }
                           opts.alt_base_mode = BASE_MODE_LINK;
   
   basedir:
   #endif
                           if (basedir_cnt >= MAX_BASEDIR)
                                   errx(1, "too many --%s directories specified",
                                       lopts[lidx].name);
                           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:
                           if (scan_scaled(optarg, &opts.min_size) == -1)
                                   err(1, "bad min-size");
                           break;
                   case OP_VERSION:
                           fprintf(stderr, "openrsync: protocol version %u\n",
                               RSYNC_PROTOCOL);
                           exit(0);
                 case 'h':                  case 'h':
                 default:                  default:
                         goto usage;                          goto usage;
Line 415 
Line 505 
   
         /* by default and for --timeout=0 disable poll_timeout */          /* by default and for --timeout=0 disable poll_timeout */
         if (poll_timeout == 0)          if (poll_timeout == 0)
                 poll_timeout = -1;                  poll_timeout = -1; else
         else  
                 poll_timeout *= 1000;                  poll_timeout *= 1000;
   
         /*          /*
Line 461 
Line 550 
   
         if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw proc exec unveil",          if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw proc exec unveil",
             NULL) == -1)              NULL) == -1)
                 err(1, "pledge");                  err(ERR_IPC, "pledge");
   
         /* Create a bidirectional socket and start our child. */          /* Create a bidirectional socket and start our child. */
   
         if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds) == -1)          if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, fds) == -1)
                 err(1, "socketpair");                  err(ERR_IPC, "socketpair");
   
         switch ((child = fork())) {          switch ((child = fork())) {
         case -1:          case -1:
                 err(1, "fork");                  err(ERR_IPC, "fork");
         case 0:          case 0:
                 close(fds[0]);                  close(fds[0]);
                 if (pledge("stdio exec", NULL) == -1)                  if (pledge("stdio exec", NULL) == -1)
                         err(1, "pledge");                          err(ERR_IPC, "pledge");
   
                 memset(&sess, 0, sizeof(struct sess));                  memset(&sess, 0, sizeof(struct sess));
                 sess.opts = &opts;                  sess.opts = &opts;
   
                 if ((args = fargs_cmdline(&sess, fargs, NULL)) == NULL) {                  args = fargs_cmdline(&sess, fargs, NULL);
                         ERRX1("fargs_cmdline");  
                         _exit(1);  
                 }  
   
                 for (i = 0; args[i] != NULL; i++)                  for (i = 0; args[i] != NULL; i++)
                         LOG2("exec[%d] = %s", i, args[i]);                          LOG2("exec[%d] = %s", i, args[i]);
   
                 /* Make sure the child's stdin is from the sender. */                  /* Make sure the child's stdin is from the sender. */
                 if (dup2(fds[1], STDIN_FILENO) == -1) {                  if (dup2(fds[1], STDIN_FILENO) == -1)
                         ERR("dup2");                          err(ERR_IPC, "dup2");
                         _exit(1);                  if (dup2(fds[1], STDOUT_FILENO) == -1)
                 }                          err(ERR_IPC, "dup2");
                 if (dup2(fds[1], STDOUT_FILENO) == -1) {  
                         ERR("dup2");  
                         _exit(1);  
                 }  
                 execvp(args[0], args);                  execvp(args[0], args);
                 _exit(1);                  _exit(ERR_IPC);
                 /* NOTREACHED */                  /* NOTREACHED */
         default:          default:
                 close(fds[1]);                  close(fds[1]);
Line 511 
Line 593 
         close(fds[0]);          close(fds[0]);
   
         if (waitpid(child, &st, 0) == -1)          if (waitpid(child, &st, 0) == -1)
                 err(1, "waitpid");                  err(ERR_WAITPID, "waitpid");
   
         /*          /*
          * If we don't already have an error (rc == 0), then inherit the           * If we don't already have an error (rc == 0), then inherit the
Line 519 
Line 601 
          * If it hasn't exited, it overrides our return value.           * If it hasn't exited, it overrides our return value.
          */           */
   
         if (WIFEXITED(st) && rc == 0)          if (rc == 0) {
                 rc = WEXITSTATUS(st);                  if (WIFEXITED(st))
         else if (!WIFEXITED(st))                          rc = WEXITSTATUS(st);
                 rc = 1;                  else if (WIFSIGNALED(st))
                           rc = ERR_TERMIMATED;
                   else
                           rc = ERR_WAITPID;
           }
   
         exit(rc);          exit(rc);
 usage:  usage:
         fprintf(stderr, "usage: %s"          fprintf(stderr, "usage: %s"
             " [-aDglnoprtvx] [-e program] [--address=sourceaddr] [--del]\n"              " [-aDglnoprtvx] [-e program] [--address=sourceaddr]\n"
             "\t[--no-motd] [--numeric-ids] [--port=portnumber] "              "\t[--compare-dest=dir] [--del] [--exclude] [--exclude-from=file]\n"
             "[--rsync-path=program]\n\t[--timeout=seconds] [--version] "              "\t[--include] [--include-from=file] [--no-motd] [--numeric-ids]\n"
             "source ... directory\n",              "\t[--port=portnumber] [--rsync-path=program] [--timeout=seconds]\n"
               "\t[--version] source ... directory\n",
             getprogname());              getprogname());
         exit(1);          exit(ERR_SYNTAX);
 }  }

Legend:
Removed from v.1.53  
changed lines
  Added in v.1.53.2.1