[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.27 and 1.28

version 1.27, 2019/02/17 20:11:42 version 1.28, 2019/02/18 21:34:54
Line 98 
Line 98 
         /* Allocations. */          /* Allocations. */
   
         if ((f = calloc(1, sizeof(struct fargs))) == NULL)          if ((f = calloc(1, sizeof(struct fargs))) == NULL)
                 err(1, "calloc");                  err(EXIT_FAILURE, "calloc");
   
         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(EXIT_FAILURE, "calloc");
   
         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(EXIT_FAILURE, "strdup");
   
         if ((f->sink = strdup(argv[i])) == NULL)          if ((f->sink = strdup(argv[i])) == NULL)
                 err(1, "strdup");                  err(EXIT_FAILURE, "strdup");
   
         /*          /*
          * Test files for its locality.           * Test files for its locality.
Line 124 
Line 124 
         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(EXIT_FAILURE, "strdup");
         }          }
   
         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 "                          errx(EXIT_FAILURE, "both source and "
                                 "destination cannot be remote files");                                  "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(EXIT_FAILURE, "strdup");
         }          }
   
         if (f->host != NULL) {          if (f->host != NULL) {
                 if (strncasecmp(f->host, "rsync://", 8) == 0) {                  if (strncasecmp(f->host, "rsync://", 8) == 0) {
                         /* rsync://host/module[/path] */                          /* rsync://host[:port]/module[/path] */
                         f->remote = 1;                          f->remote = 1;
                         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 "                                  errx(EXIT_FAILURE, "rsync protocol "
                                         "requires a module name");                                          "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)
                                 *cp = '\0';                                  *cp = '\0';
                         if ((cp = strchr(f->host, ':'))) {                          if ((cp = strchr(f->host, ':')) != NULL) {
                                 /* host:port --> extract port */                                  /* host:port --> extract port */
                                 *cp++ = '\0';                                  *cp++ = '\0';
                                 opts->port = cp;                                  opts->port = cp;
Line 169 
Line 169 
                         }                          }
                 }                  }
                 if ((len = strlen(f->host)) == 0)                  if ((len = strlen(f->host)) == 0)
                         errx(1, "empty remote host");                          errx(EXIT_FAILURE, "empty remote host");
                 if (f->remote && strlen(f->module) == 0)                  if (f->remote && strlen(f->module) == 0)
                         errx(1, "empty remote module");                          errx(EXIT_FAILURE, "empty remote module");
         }          }
   
         /* Make sure we have the same "hostspec" for all files. */          /* Make sure we have the same "hostspec" for all files. */
Line 181 
Line 181 
                         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, "remote file in "                                  errx(EXIT_FAILURE, "remote file in "
                                         "list of local sources: %s",                                          "list of local sources: %s",
                                         f->sources[i]);                                          f->sources[i]);
                         }                          }
Line 191 
Line 191 
                                     !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 "                                          errx(EXIT_FAILURE, "remote "
                                                 "daemon in list of "                                                  "daemon in list of "
                                                 "remote sources: %s",                                                  "remote sources: %s",
                                                 f->sources[i]);                                                  f->sources[i]);
                                 errx(1, "local file in "                                  errx(EXIT_FAILURE, "local file in "
                                         "list of remote sources: %s",                                          "list of remote sources: %s",
                                         f->sources[i]);                                          f->sources[i]);
                         }                          }
         } else {          } else {
                 if (f->mode != FARGS_RECEIVER)                  if (f->mode != FARGS_RECEIVER)
                         errx(1, "sender mode for remote "                          errx(EXIT_FAILURE, "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(EXIT_FAILURE, "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 248 
Line 248 
                     strncasecmp(cp, "rsync://", 8) == 0) {                      strncasecmp(cp, "rsync://", 8) == 0) {
                         /* rsync://path */                          /* rsync://path */
                         cp += 8;                          cp += 8;
                         if ((ccp = strchr(cp, ':')))    /* skip :port */  
                           /*
                            * FIXME: broken.
                            * URIs can allow colons too.
                            * Fix this after merge.
                            */
   
                           if ((ccp = strchr(cp, ':')) != NULL) /* skip :port */
                                 *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 "                                  errx(EXIT_FAILURE, "different remote "
                                         "host: %s", f->sources[i]);                                          "host: %s", f->sources[i]);
                         memmove(f->sources[i],                          memmove(f->sources[i],
                                 f->sources[i] + len + 8 + 1,                                  f->sources[i] + len + 8 + 1,
Line 265 
Line 272 
                         /* 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 "                                  errx(EXIT_FAILURE, "different remote "
                                         "host: %s", f->sources[i]);                                          "host: %s", 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 276 
Line 283 
                         /* 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 "                                  errx(EXIT_FAILURE, "different remote "
                                         "host: %s", f->sources[i]);                                          "host: %s", 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 291 
Line 298 
 {  {
         struct opts      opts;          struct opts      opts;
         pid_t            child;          pid_t            child;
         int              fds[2], rc = 0, c, st;          int              fds[2], c, st;
         struct fargs    *fargs;          struct fargs    *fargs;
         struct option    lopts[] = {          struct option    lopts[] = {
                 { "port",       required_argument, NULL,                3 },                  { "port",       required_argument, NULL,                3 },
Line 329 
Line 336 
   
         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(EXIT_FAILURE, "pledge");
   
         memset(&opts, 0, sizeof(struct opts));          memset(&opts, 0, sizeof(struct opts));
   
Line 351 
Line 358 
                         break;                          break;
                 case 'e':                  case 'e':
                         opts.ssh_prog = optarg;                          opts.ssh_prog = optarg;
                           /* Ignore. */
                         break;                          break;
                 case 'g':                  case 'g':
                         opts.preserve_gids = 1;                          opts.preserve_gids = 1;
Line 404 
Line 412 
                 goto usage;                  goto usage;
   
         if (opts.port == NULL)          if (opts.port == NULL)
                 opts.port = "rsync";                  opts.port = RSYNC_SERVICE;
   
         /*          /*
          * This is what happens when we're started with the "hidden"           * This is what happens when we're started with the "hidden"
Line 414 
Line 422 
   
         if (opts.server) {          if (opts.server) {
                 if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw unveil", NULL) == -1)                  if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw unveil", NULL) == -1)
                         err(1, "pledge");                          err(EXIT_FAILURE, "pledge");
                 return rsync_server(&opts, (size_t)argc, argv);                  c = rsync_server(&opts, (size_t)argc, argv);
                   return c ? EXIT_SUCCESS : EXIT_FAILURE;
         }          }
   
         /*          /*
Line 441 
Line 450 
                 assert(fargs->mode == FARGS_RECEIVER);                  assert(fargs->mode == FARGS_RECEIVER);
                 if (pledge("stdio unix rpath wpath cpath dpath inet fattr chown dns getpw unveil",                  if (pledge("stdio unix rpath wpath cpath dpath inet fattr chown dns getpw unveil",
                     NULL) == -1)                      NULL) == -1)
                         err(1, "pledge");                          err(EXIT_FAILURE, "pledge");
                 rc = rsync_socket(&opts, fargs);                  c = rsync_socket(&opts, fargs);
                 fargs_free(fargs);                  fargs_free(fargs);
                 return rc;                  return c ? EXIT_SUCCESS : EXIT_FAILURE;
         }          }
   
         /* Drop the dns/inet possibility. */          /* Drop the dns/inet possibility. */
   
         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(EXIT_FAILURE, "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(EXIT_FAILURE, "socketpair");
   
         if ((child = fork()) == -1) {          if ((child = fork()) == -1) {
                 close(fds[0]);                  close(fds[0]);
                 close(fds[1]);                  close(fds[1]);
                 err(1, "fork");                  err(EXIT_FAILURE, "fork");
         }          }
   
         /* Drop the fork possibility. */          /* Drop the fork possibility. */
   
         if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw exec unveil", NULL) == -1)          if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw exec unveil", NULL) == -1)
                 err(1, "pledge");                  err(EXIT_FAILURE, "pledge");
   
         if (child == 0) {          if (child == 0) {
                 close(fds[0]);                  close(fds[0]);
                 fds[0] = -1;                  fds[0] = -1;
                 if (pledge("stdio exec", NULL) == -1)                  if (pledge("stdio exec", NULL) == -1)
                         err(1, "pledge");                          err(EXIT_FAILURE, "pledge");
                 rsync_child(&opts, fds[1], fargs);                  rsync_child(&opts, fds[1], fargs);
                 /* NOTREACHED */                  /* NOTREACHED */
         }          }
Line 481 
Line 490 
         close(fds[1]);          close(fds[1]);
         fds[1] = -1;          fds[1] = -1;
         if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw unveil", NULL) == -1)          if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw unveil", NULL) == -1)
                 err(1, "pledge");                  err(EXIT_FAILURE, "pledge");
         rc = rsync_client(&opts, fds[0], fargs);          c = rsync_client(&opts, fds[0], fargs);
         fargs_free(fargs);          fargs_free(fargs);
   
         /*          /*
Line 491 
Line 500 
          * So close the connection here so that they don't hang.           * So close the connection here so that they don't hang.
          */           */
   
         if (!rc) {          if (!c) {
                 close(fds[0]);                  close(fds[0]);
                 fds[0] = -1;                  fds[0] = -1;
         }          }
   
         if (waitpid(child, &st, 0) == -1)          if (waitpid(child, &st, 0) == -1)
                 err(1, "waitpid");                  err(EXIT_FAILURE, "waitpid");
         if (!(WIFEXITED(st) && WEXITSTATUS(st) == 0))          if (!(WIFEXITED(st) && WEXITSTATUS(st) == EXIT_SUCCESS))
                 rc = 0;                  c = 0;
   
         if (fds[0] != -1)          if (fds[0] != -1)
                 close(fds[0]);                  close(fds[0]);
         return rc;          return c ? EXIT_SUCCESS : EXIT_FAILURE;
 usage:  usage:
         fprintf(stderr, "usage: %s [-Daglnoprtv] "          fprintf(stderr, "usage: %s [-Daghlnoprtv] "
                 "[-e ssh-prog] [--delete] [--rsync-path=prog] src ... dst\n",                  "[-e ssh-prog] [--delete] "
                   "[--port=port] [--rsync-path=prog] src ... dst\n",
                 getprogname());                  getprogname());
         return 1;          return EXIT_FAILURE;
 }  }

Legend:
Removed from v.1.27  
changed lines
  Added in v.1.28