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

Diff for /src/usr.bin/ssh/scp.c between version 1.218 and 1.219

version 1.218, 2021/08/07 00:00:33 version 1.219, 2021/08/07 00:06:30
Line 113 
Line 113 
 #define COPY_BUFLEN     16384  #define COPY_BUFLEN     16384
   
 int do_cmd(char *program, char *host, char *remuser, int port, char *cmd,  int do_cmd(char *program, char *host, char *remuser, int port, char *cmd,
     int *fdin, int *fdout);      int *fdin, int *fdout, pid_t *pidp);
 int do_cmd2(char *host, char *remuser, int port, char *cmd,  int do_cmd2(char *host, char *remuser, int port, char *cmd,
     int fdin, int fdout);      int fdin, int fdout);
   
Line 149 
Line 149 
   
 /* This is used to store the pid of ssh_program */  /* This is used to store the pid of ssh_program */
 pid_t do_cmd_pid = -1;  pid_t do_cmd_pid = -1;
   pid_t do_cmd_pid2 = -1;
   
 /* Needed for sftp */  /* Needed for sftp */
 volatile sig_atomic_t interrupted = 0;  volatile sig_atomic_t interrupted = 0;
Line 163 
Line 164 
                 kill(do_cmd_pid, signo ? signo : SIGTERM);                  kill(do_cmd_pid, signo ? signo : SIGTERM);
                 waitpid(do_cmd_pid, NULL, 0);                  waitpid(do_cmd_pid, NULL, 0);
         }          }
           if (do_cmd_pid2 > 1) {
                   kill(do_cmd_pid2, signo ? signo : SIGTERM);
                   waitpid(do_cmd_pid2, NULL, 0);
           }
   
         if (signo)          if (signo)
                 _exit(1);                  _exit(1);
Line 170 
Line 175 
 }  }
   
 static void  static void
 suspchild(int signo)  suspone(int pid, int signo)
 {  {
         int status;          int status;
   
         if (do_cmd_pid > 1) {          if (pid > 1) {
                 kill(do_cmd_pid, signo);                  kill(pid, signo);
                 while (waitpid(do_cmd_pid, &status, WUNTRACED) == -1 &&                  while (waitpid(pid, &status, WUNTRACED) == -1 &&
                     errno == EINTR)                      errno == EINTR)
                         ;                          ;
                 kill(getpid(), SIGSTOP);  
         }          }
 }  }
   
   static void
   suspchild(int signo)
   {
           suspone(do_cmd_pid, signo);
           suspone(do_cmd_pid2, signo);
           kill(getpid(), SIGSTOP);
   }
   
 static int  static int
 do_local_cmd(arglist *a)  do_local_cmd(arglist *a)
 {  {
Line 233 
Line 245 
   
 int  int
 do_cmd(char *program, char *host, char *remuser, int port, char *cmd,  do_cmd(char *program, char *host, char *remuser, int port, char *cmd,
     int *fdin, int *fdout)      int *fdin, int *fdout, int *pid)
 {  {
         int pin[2], pout[2], reserved[2];          int pin[2], pout[2], reserved[2];
   
Line 268 
Line 280 
         ssh_signal(SIGTTOU, suspchild);          ssh_signal(SIGTTOU, suspchild);
   
         /* Fork a child to execute the command on the remote host using ssh. */          /* Fork a child to execute the command on the remote host using ssh. */
         do_cmd_pid = fork();          *pid = fork();
         if (do_cmd_pid == 0) {          if (*pid == 0) {
                 /* Child. */                  /* Child. */
                 close(pin[1]);                  close(pin[1]);
                 close(pout[0]);                  close(pout[0]);
Line 294 
Line 306 
                 execvp(program, args.list);                  execvp(program, args.list);
                 perror(program);                  perror(program);
                 exit(1);                  exit(1);
         } else if (do_cmd_pid == -1) {          } else if (*pid == -1) {
                 fatal("fork: %s", strerror(errno));                  fatal("fork: %s", strerror(errno));
         }          }
         /* Parent.  Close the other side, and return the local side. */          /* Parent.  Close the other side, and return the local side. */
Line 314 
Line 326 
  * This way the input and output of two commands can be connected.   * This way the input and output of two commands can be connected.
  */   */
 int  int
 do_cmd2(char *host, char *remuser, int port, char *cmd, int fdin, int fdout)  do_cmd2(char *host, char *remuser, int port, char *cmd,
       int fdin, int fdout)
 {  {
         pid_t pid;  
         int status;          int status;
           pid_t pid;
   
         if (verbose_mode)          if (verbose_mode)
                 fmprintf(stderr,                  fmprintf(stderr,
Line 377 
Line 390 
   
 struct passwd *pwd;  struct passwd *pwd;
 uid_t userid;  uid_t userid;
 int errs, remin, remout;  int errs, remin, remout, remin2, remout2;
 int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory;  int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory;
   
 #define CMDNEEDS        64  #define CMDNEEDS        64
Line 398 
Line 411 
   
 void source_sftp(int, char *, char *, struct sftp_conn *, char **);  void source_sftp(int, char *, char *, struct sftp_conn *, char **);
 void sink_sftp(int, char *, const char *, struct sftp_conn *);  void sink_sftp(int, char *, const char *, struct sftp_conn *);
   void throughlocal_sftp(struct sftp_conn *, struct sftp_conn *,
       char *, char *, char **);
   
 int  int
 main(int argc, char **argv)  main(int argc, char **argv)
Line 910 
Line 925 
 }  }
   
 static struct sftp_conn *  static struct sftp_conn *
 do_sftp_connect(char *host, char *user, int port, char *sftp_direct)  do_sftp_connect(char *host, char *user, int port, char *sftp_direct,
      int *reminp, int *remoutp, int *pidp)
 {  {
         if (sftp_direct == NULL) {          if (sftp_direct == NULL) {
                 addargs(&args, "-s");                  addargs(&args, "-s");
                 if (do_cmd(ssh_program, host, user, port, "sftp",                  if (do_cmd(ssh_program, host, user, port, "sftp",
                     &remin, &remout) < 0)                      reminp, remoutp, pidp) < 0)
                         return NULL;                          return NULL;
   
         } else {          } else {
                 args.list = NULL;                  args.list = NULL;
                 addargs(&args, "sftp-server");                  addargs(&args, "sftp-server");
                 if (do_cmd(sftp_direct, host, NULL, -1, "sftp",                  if (do_cmd(sftp_direct, host, NULL, -1, "sftp",
                     &remin, &remout) < 0)                      reminp, remoutp, pidp) < 0)
                         return NULL;                          return NULL;
         }          }
         return do_init(remin, remout, 32768, 64, limit_kbps);          return do_init(*reminp, *remoutp, 32768, 64, limit_kbps);
 }  }
   
 void  void
Line 935 
Line 951 
         char *bp, *tuser, *thost, *targ;          char *bp, *tuser, *thost, *targ;
         char *remote_path = NULL;          char *remote_path = NULL;
         int sport = -1, tport = -1;          int sport = -1, tport = -1;
         struct sftp_conn *conn = NULL;          struct sftp_conn *conn = NULL, *conn2 = NULL;
         arglist alist;          arglist alist;
         int i, r;          int i, r, status;
         u_int j;          u_int j;
   
         memset(&alist, '\0', sizeof(alist));          memset(&alist, '\0', sizeof(alist));
Line 978 
Line 994 
                         continue;                          continue;
                 }                  }
                 if (host && throughlocal) {     /* extended remote to remote */                  if (host && throughlocal) {     /* extended remote to remote */
                         /* XXX uses scp; need to support SFTP remote-remote */                          if (mode == MODE_SFTP) {
                         xasprintf(&bp, "%s -f %s%s", cmd,                                  if (remin == -1) {
                             *src == '-' ? "-- " : "", src);                                          /* Connect to dest now */
                         if (do_cmd(ssh_program, host, suser, sport, bp,                                          conn = do_sftp_connect(thost, tuser,
                             &remin, &remout) < 0)                                              tport, sftp_direct,
                                 exit(1);                                              &remin, &remout, &do_cmd_pid);
                         free(bp);                                          if (conn == NULL) {
                         xasprintf(&bp, "%s -t %s%s", cmd,                                                  fatal("Unable to open "
                             *targ == '-' ? "-- " : "", targ);                                                      "destination connection");
                         if (do_cmd2(thost, tuser, tport, bp, remin, remout) < 0)                                          }
                                 exit(1);                                          debug3_f("origin in %d out %d pid %ld",
                         free(bp);                                              remin, remout, (long)do_cmd_pid);
                         (void) close(remin);                                  }
                         (void) close(remout);                                  /*
                         remin = remout = -1;                                   * XXX remember suser/host/sport and only
                                    * reconnect if they change between arguments.
                                    * would save reconnections for cases like
                                    * scp -3 hosta:/foo hosta:/bar hostb:
                                    */
                                   /* Connect to origin now */
                                   conn2 = do_sftp_connect(host, suser,
                                       sport, sftp_direct,
                                       &remin2, &remout2, &do_cmd_pid2);
                                   if (conn2 == NULL) {
                                           fatal("Unable to open "
                                               "source connection");
                                   }
                                   debug3_f("destination in %d out %d pid %ld",
                                       remin2, remout2, (long)do_cmd_pid2);
                                   throughlocal_sftp(conn2, conn, src, targ,
                                       &remote_path);
                                   (void) close(remin2);
                                   (void) close(remout2);
                                   remin2 = remout2 = -1;
                                   if (waitpid(do_cmd_pid2, &status, 0) == -1)
                                           ++errs;
                                   else if (!WIFEXITED(status) ||
                                       WEXITSTATUS(status) != 0)
                                           ++errs;
                                   do_cmd_pid2 = -1;
                                   continue;
                           } else {
                                   xasprintf(&bp, "%s -f %s%s", cmd,
                                       *src == '-' ? "-- " : "", src);
                                   if (do_cmd(ssh_program, host, suser, sport,
                                       bp, &remin, &remout, &do_cmd_pid) < 0)
                                           exit(1);
                                   free(bp);
                                   xasprintf(&bp, "%s -t %s%s", cmd,
                                       *targ == '-' ? "-- " : "", targ);
                                   if (do_cmd2(thost, tuser, tport, bp,
                                       remin, remout) < 0)
                                           exit(1);
                                   free(bp);
                                   (void) close(remin);
                                   (void) close(remout);
                                   remin = remout = -1;
                           }
                 } else if (host) {      /* standard remote to remote */                  } else if (host) {      /* standard remote to remote */
                         /*                          /*
                          * Second remote user is passed to first remote side                           * Second remote user is passed to first remote side
Line 1041 
Line 1100 
                                 if (remin == -1) {                                  if (remin == -1) {
                                         /* Connect to remote now */                                          /* Connect to remote now */
                                         conn = do_sftp_connect(thost, tuser,                                          conn = do_sftp_connect(thost, tuser,
                                             tport, sftp_direct);                                              tport, sftp_direct,
                                               &remin, &remout, &do_cmd_pid);
                                         if (conn == NULL) {                                          if (conn == NULL) {
                                                 fatal("Unable to open sftp "                                                  fatal("Unable to open sftp "
                                                     "connection");                                                      "connection");
Line 1058 
Line 1118 
                                 xasprintf(&bp, "%s -t %s%s", cmd,                                  xasprintf(&bp, "%s -t %s%s", cmd,
                                     *targ == '-' ? "-- " : "", targ);                                      *targ == '-' ? "-- " : "", targ);
                                 if (do_cmd(ssh_program, thost, tuser, tport, bp,                                  if (do_cmd(ssh_program, thost, tuser, tport, bp,
                                     &remin, &remout) < 0)                                      &remin, &remout, &do_cmd_pid) < 0)
                                         exit(1);                                          exit(1);
                                 if (response() < 0)                                  if (response() < 0)
                                         exit(1);                                          exit(1);
Line 1123 
Line 1183 
                 }                  }
                 /* Remote to local. */                  /* Remote to local. */
                 if (mode == MODE_SFTP) {                  if (mode == MODE_SFTP) {
                         conn = do_sftp_connect(host, suser, sport, sftp_direct);                          conn = do_sftp_connect(host, suser, sport,
                               sftp_direct, &remin, &remout, &do_cmd_pid);
                         if (conn == NULL) {                          if (conn == NULL) {
                                 error("Couldn't make sftp connection "                                  error("Couldn't make sftp connection "
                                     "to server");                                      "to server");
Line 1143 
Line 1204 
                 /* SCP */                  /* SCP */
                 xasprintf(&bp, "%s -f %s%s",                  xasprintf(&bp, "%s -f %s%s",
                     cmd, *src == '-' ? "-- " : "", src);                      cmd, *src == '-' ? "-- " : "", src);
                 if (do_cmd(ssh_program, host, suser, sport, bp, &remin,                  if (do_cmd(ssh_program, host, suser, sport, bp,
                     &remout) < 0) {                      &remin, &remout, &do_cmd_pid) < 0) {
                         free(bp);                          free(bp);
                         ++errs;                          ++errs;
                         continue;                          continue;
Line 1765 
Line 1826 
         free(patterns);          free(patterns);
         run_err("protocol error: %s", why);          run_err("protocol error: %s", why);
         exit(1);          exit(1);
   }
   
   void
   throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to,
       char *src, char *targ, char **to_remote_path)
   {
           char *target = NULL, *filename = NULL, *abs_dst = NULL;
           char *abs_src = NULL, *tmp = NULL, *from_remote_path;
           glob_t g;
           int i, r, targetisdir, err = 0;
   
           if (*to_remote_path == NULL) {
                   *to_remote_path = do_realpath(to, ".");
                   if (*to_remote_path == NULL) {
                           fatal("Unable to determine destination remote "
                               "working directory");
                   }
           }
   
           if ((from_remote_path = do_realpath(from, ".")) == NULL) {
                   fatal("Unable to determine source remote "
                       "working directory");
           }
   
           if ((filename = basename(src)) == NULL)
                   fatal("basename %s: %s", src, strerror(errno));
   
           abs_src = xstrdup(src);
           abs_src = make_absolute(abs_src, from_remote_path);
           free(from_remote_path);
           target = xstrdup(targ);
           target = make_absolute(target, *to_remote_path);
           memset(&g, 0, sizeof(g));
   
           targetisdir = remote_is_dir(to, target);
           if (!targetisdir && targetshouldbedirectory) {
                   error("Destination path \"%s\" is not a directory", target);
                   err = -1;
                   goto out;
           }
   
           debug3_f("copying remote %s to remote %s", abs_src, target);
           if ((r = remote_glob(from, abs_src, GLOB_MARK, NULL, &g)) != 0) {
                   if (r == GLOB_NOSPACE)
                           error("Too many glob matches for \"%s\".", abs_src);
                   else
                           error("File \"%s\" not found.", abs_src);
                   err = -1;
                   goto out;
           }
   
           for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
                   tmp = xstrdup(g.gl_pathv[i]);
                   if ((filename = basename(tmp)) == NULL) {
                           error("basename %s: %s", tmp, strerror(errno));
                           err = -1;
                           goto out;
                   }
   
                   if (targetisdir)
                           abs_dst = path_append(target, filename);
                   else
                           abs_dst = xstrdup(target);
   
                   debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
                   if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
                           if (crossload_dir(from, to, g.gl_pathv[i], abs_dst,
                               NULL, pflag, 1) == -1)
                                   err = -1;
                   } else {
                           if (do_crossload(from, to, g.gl_pathv[i], abs_dst, NULL,
                               pflag) == -1)
                                   err = -1;
                   }
                   free(abs_dst);
                   abs_dst = NULL;
                   free(tmp);
                   tmp = NULL;
           }
   
   out:
           free(abs_src);
           free(abs_dst);
           free(target);
           free(tmp);
           globfree(&g);
           if (err == -1)
                   fatal("Failed to download file '%s'", src);
 }  }
   
 int  int

Legend:
Removed from v.1.218  
changed lines
  Added in v.1.219