[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.125 and 1.125.2.2

version 1.125, 2005/07/27 10:39:03 version 1.125.2.2, 2006/10/06 03:19:33
Line 1 
Line 1 
   /* $OpenBSD$ */
 /*  /*
  * scp - secure remote copy.  This is basically patched BSD rcp which   * scp - secure remote copy.  This is basically patched BSD rcp which
  * uses ssh to do the data transfer (instead of using rcmd).   * uses ssh to do the data transfer (instead of using rcmd).
Line 70 
Line 71 
  *   *
  */   */
   
 #include "includes.h"  #include <sys/param.h>
 RCSID("$OpenBSD$");  #include <sys/types.h>
   #include <sys/wait.h>
   #include <sys/stat.h>
   #include <sys/time.h>
   #include <sys/uio.h>
   
   #include <ctype.h>
   #include <dirent.h>
   #include <errno.h>
   #include <fcntl.h>
   #include <pwd.h>
   #include <signal.h>
   #include <stdarg.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <time.h>
   #include <unistd.h>
   
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "atomicio.h"  #include "atomicio.h"
 #include "pathnames.h"  #include "pathnames.h"
Line 80 
Line 98 
 #include "misc.h"  #include "misc.h"
 #include "progressmeter.h"  #include "progressmeter.h"
   
 int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc);  int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout);
   
 void bwlimit(int);  void bwlimit(int);
   
Line 118 
Line 136 
         exit(1);          exit(1);
 }  }
   
   static int
   do_local_cmd(arglist *a)
   {
           u_int i;
           int status;
           pid_t pid;
   
           if (a->num == 0)
                   fatal("do_local_cmd: no arguments");
   
           if (verbose_mode) {
                   fprintf(stderr, "Executing:");
                   for (i = 0; i < a->num; i++)
                           fprintf(stderr, " %s", a->list[i]);
                   fprintf(stderr, "\n");
           }
           if ((pid = fork()) == -1)
                   fatal("do_local_cmd: fork: %s", strerror(errno));
   
           if (pid == 0) {
                   execvp(a->list[0], a->list);
                   perror(a->list[0]);
                   exit(1);
           }
   
           do_cmd_pid = pid;
           signal(SIGTERM, killchild);
           signal(SIGINT, killchild);
           signal(SIGHUP, killchild);
   
           while (waitpid(pid, &status, 0) == -1)
                   if (errno != EINTR)
                           fatal("do_local_cmd: waitpid: %s", strerror(errno));
   
           do_cmd_pid = -1;
   
           if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
                   return (-1);
   
           return (0);
   }
   
 /*  /*
  * This function executes the given command as the specified user on the   * This function executes the given command as the specified user on the
  * given host.  This returns < 0 if execution fails, and >= 0 otherwise. This   * given host.  This returns < 0 if execution fails, and >= 0 otherwise. This
Line 125 
Line 185 
  */   */
   
 int  int
 do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)  do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
 {  {
         int pin[2], pout[2], reserved[2];          int pin[2], pout[2], reserved[2];
   
Line 139 
Line 199 
          * Reserve two descriptors so that the real pipes won't get           * Reserve two descriptors so that the real pipes won't get
          * descriptors 0 and 1 because that will screw up dup2 below.           * descriptors 0 and 1 because that will screw up dup2 below.
          */           */
         pipe(reserved);          if (pipe(reserved) < 0)
                   fatal("pipe: %s", strerror(errno));
   
         /* Create a socket pair for communicating with ssh. */          /* Create a socket pair for communicating with ssh. */
         if (pipe(pin) < 0)          if (pipe(pin) < 0)
Line 162 
Line 223 
                 close(pin[0]);                  close(pin[0]);
                 close(pout[1]);                  close(pout[1]);
   
                 args.list[0] = ssh_program;                  replacearg(&args, 0, "%s", ssh_program);
                 if (remuser != NULL)                  if (remuser != NULL)
                         addargs(&args, "-l%s", remuser);                          addargs(&args, "-l%s", remuser);
                 addargs(&args, "%s", host);                  addargs(&args, "%s", host);
Line 192 
Line 253 
   
 BUF *allocbuf(BUF *, int, int);  BUF *allocbuf(BUF *, int, int);
 void lostconn(int);  void lostconn(int);
 void nospace(void);  
 int okname(char *);  int okname(char *);
 void run_err(const char *,...);  void run_err(const char *,...);
 void verifydir(char *);  void verifydir(char *);
Line 216 
Line 276 
 int  int
 main(int argc, char **argv)  main(int argc, char **argv)
 {  {
         int ch, fflag, tflag, status;          int ch, fflag, tflag, status, n;
         double speed;          double speed;
         char *targ, *endp;          char *targ, *endp, **newargv;
         extern char *optarg;          extern char *optarg;
         extern int optind;          extern int optind;
   
           /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
           sanitise_stdfd();
   
           /* Copy argv, because we modify it */
           newargv = xcalloc(MAX(argc + 1, 1), sizeof(*newargv));
           for (n = 0; n < argc; n++)
                   newargv[n] = xstrdup(argv[n]);
           argv = newargv;
   
           memset(&args, '\0', sizeof(args));
         args.list = NULL;          args.list = NULL;
         addargs(&args, "ssh");          /* overwritten with ssh_program */          addargs(&args, "%s", ssh_program);
         addargs(&args, "-x");          addargs(&args, "-x");
         addargs(&args, "-oForwardAgent no");          addargs(&args, "-oForwardAgent no");
           addargs(&args, "-oPermitLocalCommand no");
         addargs(&args, "-oClearAllForwardings yes");          addargs(&args, "-oClearAllForwardings yes");
   
         fflag = tflag = 0;          fflag = tflag = 0;
Line 331 
Line 402 
         if ((targ = colon(argv[argc - 1])))     /* Dest is remote host. */          if ((targ = colon(argv[argc - 1])))     /* Dest is remote host. */
                 toremote(targ, argc, argv);                  toremote(targ, argc, argv);
         else {          else {
                 tolocal(argc, argv);    /* Dest is local host. */  
                 if (targetshouldbedirectory)                  if (targetshouldbedirectory)
                         verifydir(argv[argc - 1]);                          verifydir(argv[argc - 1]);
                   tolocal(argc, argv);    /* Dest is local host. */
         }          }
         /*          /*
          * Finally check the exit status of the ssh process, if one was forked           * Finally check the exit status of the ssh process, if one was forked
Line 357 
Line 428 
 void  void
 toremote(char *targ, int argc, char **argv)  toremote(char *targ, int argc, char **argv)
 {  {
         int i, len;  
         char *bp, *host, *src, *suser, *thost, *tuser, *arg;          char *bp, *host, *src, *suser, *thost, *tuser, *arg;
           arglist alist;
           int i;
   
           memset(&alist, '\0', sizeof(alist));
           alist.list = NULL;
   
         *targ++ = 0;          *targ++ = 0;
         if (*targ == 0)          if (*targ == 0)
                 targ = ".";                  targ = ".";
Line 376 
Line 451 
                 tuser = NULL;                  tuser = NULL;
         }          }
   
           if (tuser != NULL && !okname(tuser)) {
                   xfree(arg);
                   return;
           }
   
         for (i = 0; i < argc - 1; i++) {          for (i = 0; i < argc - 1; i++) {
                 src = colon(argv[i]);                  src = colon(argv[i]);
                 if (src) {      /* remote to remote */                  if (src) {      /* remote to remote */
                         static char *ssh_options =                          freeargs(&alist);
                             "-x -o'ClearAllForwardings yes'";                          addargs(&alist, "%s", ssh_program);
                           if (verbose_mode)
                                   addargs(&alist, "-v");
                           addargs(&alist, "-x");
                           addargs(&alist, "-oClearAllForwardings yes");
                           addargs(&alist, "-n");
   
                         *src++ = 0;                          *src++ = 0;
                         if (*src == 0)                          if (*src == 0)
                                 src = ".";                                  src = ".";
                         host = strrchr(argv[i], '@');                          host = strrchr(argv[i], '@');
                         len = strlen(ssh_program) + strlen(argv[i]) +  
                             strlen(src) + (tuser ? strlen(tuser) : 0) +  
                             strlen(thost) + strlen(targ) +  
                             strlen(ssh_options) + CMDNEEDS + 20;  
                         bp = xmalloc(len);  
                         if (host) {                          if (host) {
                                 *host++ = 0;                                  *host++ = 0;
                                 host = cleanhostname(host);                                  host = cleanhostname(host);
                                 suser = argv[i];                                  suser = argv[i];
                                 if (*suser == '\0')                                  if (*suser == '\0')
                                         suser = pwd->pw_name;                                          suser = pwd->pw_name;
                                 else if (!okname(suser)) {                                  else if (!okname(suser))
                                         xfree(bp);  
                                         continue;                                          continue;
                                 }                                  addargs(&alist, "-l");
                                 if (tuser && !okname(tuser)) {                                  addargs(&alist, "%s", suser);
                                         xfree(bp);  
                                         continue;  
                                 }  
                                 snprintf(bp, len,  
                                     "%s%s %s -n "  
                                     "-l %s %s %s %s '%s%s%s:%s'",  
                                     ssh_program, verbose_mode ? " -v" : "",  
                                     ssh_options, suser, host, cmd, src,  
                                     tuser ? tuser : "", tuser ? "@" : "",  
                                     thost, targ);  
                         } else {                          } else {
                                 host = cleanhostname(argv[i]);                                  host = cleanhostname(argv[i]);
                                 snprintf(bp, len,  
                                     "exec %s%s %s -n %s "  
                                     "%s %s '%s%s%s:%s'",  
                                     ssh_program, verbose_mode ? " -v" : "",  
                                     ssh_options, host, cmd, src,  
                                     tuser ? tuser : "", tuser ? "@" : "",  
                                     thost, targ);  
                         }                          }
                         if (verbose_mode)                          addargs(&alist, "%s", host);
                                 fprintf(stderr, "Executing: %s\n", bp);                          addargs(&alist, "%s", cmd);
                         if (system(bp) != 0)                          addargs(&alist, "%s", src);
                           addargs(&alist, "%s%s%s:%s",
                               tuser ? tuser : "", tuser ? "@" : "",
                               thost, targ);
                           if (do_local_cmd(&alist) != 0)
                                 errs = 1;                                  errs = 1;
                         (void) xfree(bp);  
                 } else {        /* local to remote */                  } else {        /* local to remote */
                         if (remin == -1) {                          if (remin == -1) {
                                 len = strlen(targ) + CMDNEEDS + 20;                                  xasprintf(&bp, "%s -t %s", cmd, targ);
                                 bp = xmalloc(len);  
                                 (void) snprintf(bp, len, "%s -t %s", cmd, targ);  
                                 host = cleanhostname(thost);                                  host = cleanhostname(thost);
                                 if (do_cmd(host, tuser, bp, &remin,                                  if (do_cmd(host, tuser, bp, &remin,
                                     &remout, argc) < 0)                                      &remout) < 0)
                                         exit(1);                                          exit(1);
                                 if (response() < 0)                                  if (response() < 0)
                                         exit(1);                                          exit(1);
Line 442 
Line 507 
                         source(1, argv + i);                          source(1, argv + i);
                 }                  }
         }          }
           xfree(arg);
 }  }
   
 void  void
 tolocal(int argc, char **argv)  tolocal(int argc, char **argv)
 {  {
         int i, len;  
         char *bp, *host, *src, *suser;          char *bp, *host, *src, *suser;
           arglist alist;
           int i;
   
           memset(&alist, '\0', sizeof(alist));
           alist.list = NULL;
   
         for (i = 0; i < argc - 1; i++) {          for (i = 0; i < argc - 1; i++) {
                 if (!(src = colon(argv[i]))) {  /* Local to local. */                  if (!(src = colon(argv[i]))) {  /* Local to local. */
                         len = strlen(_PATH_CP) + strlen(argv[i]) +                          freeargs(&alist);
                             strlen(argv[argc - 1]) + 20;                          addargs(&alist, "%s", _PATH_CP);
                         bp = xmalloc(len);                          if (iamrecursive)
                         (void) snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP,                                  addargs(&alist, "-r");
                             iamrecursive ? " -r" : "", pflag ? " -p" : "",                          if (pflag)
                             argv[i], argv[argc - 1]);                                  addargs(&alist, "-p");
                         if (verbose_mode)                          addargs(&alist, "%s", argv[i]);
                                 fprintf(stderr, "Executing: %s\n", bp);                          addargs(&alist, "%s", argv[argc-1]);
                         if (system(bp))                          if (do_local_cmd(&alist))
                                 ++errs;                                  ++errs;
                         (void) xfree(bp);  
                         continue;                          continue;
                 }                  }
                 *src++ = 0;                  *src++ = 0;
Line 478 
Line 547 
                                 suser = pwd->pw_name;                                  suser = pwd->pw_name;
                 }                  }
                 host = cleanhostname(host);                  host = cleanhostname(host);
                 len = strlen(src) + CMDNEEDS + 20;                  xasprintf(&bp, "%s -f %s", cmd, src);
                 bp = xmalloc(len);                  if (do_cmd(host, suser, bp, &remin, &remout) < 0) {
                 (void) snprintf(bp, len, "%s -f %s", cmd, src);  
                 if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) {  
                         (void) xfree(bp);                          (void) xfree(bp);
                         ++errs;                          ++errs;
                         continue;                          continue;
Line 563 
Line 630 
                 if (response() < 0)                  if (response() < 0)
                         goto next;                          goto next;
                 if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) {                  if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) {
 next:                   (void) close(fd);  next:                   if (fd != -1) {
                                   (void) close(fd);
                                   fd = -1;
                           }
                         continue;                          continue;
                 }                  }
                 if (showprogress)                  if (showprogress)
Line 592 
Line 662 
                 if (showprogress)                  if (showprogress)
                         stop_progress_meter();                          stop_progress_meter();
   
                 if (close(fd) < 0 && !haderr)                  if (fd != -1) {
                         haderr = errno;                          if (close(fd) < 0 && !haderr)
                                   haderr = errno;
                           fd = -1;
                   }
                 if (!haderr)                  if (!haderr)
                         (void) atomicio(vwrite, remout, "", 1);                          (void) atomicio(vwrite, remout, "", 1);
                 else                  else
Line 720 
Line 793 
         BUF *bp;          BUF *bp;
         off_t i;          off_t i;
         size_t j, count;          size_t j, count;
         int amt, exists, first, mask, mode, ofd, omode;          int amt, exists, first, ofd;
           mode_t mode, omode, mask;
         off_t size, statbytes;          off_t size, statbytes;
         int setimes, targisdir, wrerrno = 0;          int setimes, targisdir, wrerrno = 0;
         char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];          char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
Line 1032 
Line 1106 
         va_list ap;          va_list ap;
   
         ++errs;          ++errs;
         if (fp == NULL && !(fp = fdopen(remout, "w")))          if (fp != NULL || (remout != -1 && (fp = fdopen(remout, "w")))) {
                 return;                  (void) fprintf(fp, "%c", 0x01);
         (void) fprintf(fp, "%c", 0x01);                  (void) fprintf(fp, "scp: ");
         (void) fprintf(fp, "scp: ");                  va_start(ap, fmt);
         va_start(ap, fmt);                  (void) vfprintf(fp, fmt, ap);
         (void) vfprintf(fp, fmt, ap);                  va_end(ap);
         va_end(ap);                  (void) fprintf(fp, "\n");
         (void) fprintf(fp, "\n");                  (void) fflush(fp);
         (void) fflush(fp);          }
   
         if (!iamremote) {          if (!iamremote) {
                 va_start(ap, fmt);                  va_start(ap, fmt);
Line 1112 
Line 1186 
         if (bp->buf == NULL)          if (bp->buf == NULL)
                 bp->buf = xmalloc(size);                  bp->buf = xmalloc(size);
         else          else
                 bp->buf = xrealloc(bp->buf, size);                  bp->buf = xrealloc(bp->buf, 1, size);
         memset(bp->buf, 0, size);          memset(bp->buf, 0, size);
         bp->cnt = size;          bp->cnt = size;
         return (bp);          return (bp);

Legend:
Removed from v.1.125  
changed lines
  Added in v.1.125.2.2