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

Diff for /src/usr.bin/ssh/Attic/sftp-int.c between version 1.49 and 1.49.2.1

version 1.49, 2002/09/12 00:13:06 version 1.49.2.1, 2003/04/01 00:12:14
Line 49 
Line 49 
 /* Number of concurrent outstanding requests */  /* Number of concurrent outstanding requests */
 extern int num_requests;  extern int num_requests;
   
   /* This is set to 0 if the progressmeter is not desired. */
   int showprogress = 1;
   
 /* Seperators for interactive commands */  /* Seperators for interactive commands */
 #define WHITESPACE " \t\r\n"  #define WHITESPACE " \t\r\n"
   
Line 75 
Line 78 
 #define I_SHELL         20  #define I_SHELL         20
 #define I_SYMLINK       21  #define I_SYMLINK       21
 #define I_VERSION       22  #define I_VERSION       22
   #define I_PROGRESS      23
   
 struct CMD {  struct CMD {
         const char *c;          const char *c;
         const int n;          const int n;
 };  };
   
 const struct CMD cmds[] = {  static const struct CMD cmds[] = {
         { "bye",        I_QUIT },          { "bye",        I_QUIT },
         { "cd",         I_CHDIR },          { "cd",         I_CHDIR },
         { "chdir",      I_CHDIR },          { "chdir",      I_CHDIR },
Line 102 
Line 106 
         { "ls",         I_LS },          { "ls",         I_LS },
         { "lumask",     I_LUMASK },          { "lumask",     I_LUMASK },
         { "mkdir",      I_MKDIR },          { "mkdir",      I_MKDIR },
           { "progress",   I_PROGRESS },
         { "put",        I_PUT },          { "put",        I_PUT },
         { "mput",       I_PUT },          { "mput",       I_PUT },
         { "pwd",        I_PWD },          { "pwd",        I_PWD },
Line 134 
Line 139 
         printf("ls [path]                     Display remote directory listing\n");          printf("ls [path]                     Display remote directory listing\n");
         printf("lumask umask                  Set local umask to 'umask'\n");          printf("lumask umask                  Set local umask to 'umask'\n");
         printf("mkdir path                    Create remote directory\n");          printf("mkdir path                    Create remote directory\n");
           printf("progress                      Toggle display of progress meter\n");
         printf("put local-path [remote-path]  Upload file\n");          printf("put local-path [remote-path]  Upload file\n");
         printf("pwd                           Display remote working directory\n");          printf("pwd                           Display remote working directory\n");
         printf("exit                          Quit sftp\n");          printf("exit                          Quit sftp\n");
Line 377 
Line 383 
 }  }
   
 static int  static int
   is_reg(char *path)
   {
           struct stat sb;
   
           if (stat(path, &sb) == -1)
                   fatal("stat %s: %s", path, strerror(errno));
   
           return(S_ISREG(sb.st_mode));
   }
   
   static int
 remote_is_dir(struct sftp_conn *conn, char *path)  remote_is_dir(struct sftp_conn *conn, char *path)
 {  {
         Attrib *a;          Attrib *a;
Line 427 
Line 444 
                         err = -1;                          err = -1;
                         goto out;                          goto out;
                 }                  }
                 printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst);  
                 err = do_download(conn, g.gl_pathv[0], abs_dst, pflag);                  err = do_download(conn, g.gl_pathv[0], abs_dst, pflag);
                 goto out;                  goto out;
         }          }
Line 491 
Line 507 
   
         /* Only one match, dst may be file, directory or unspecified */          /* Only one match, dst may be file, directory or unspecified */
         if (g.gl_pathv[0] && g.gl_matchc == 1) {          if (g.gl_pathv[0] && g.gl_matchc == 1) {
                   if (!is_reg(g.gl_pathv[0])) {
                           error("Can't upload %s: not a regular file",
                               g.gl_pathv[0]);
                           err = 1;
                           goto out;
                   }
                 if (tmp_dst) {                  if (tmp_dst) {
                         /* If directory specified, append filename */                          /* If directory specified, append filename */
                         if (remote_is_dir(conn, tmp_dst)) {                          if (remote_is_dir(conn, tmp_dst)) {
Line 509 
Line 531 
                         }                          }
                         abs_dst = make_absolute(abs_dst, pwd);                          abs_dst = make_absolute(abs_dst, pwd);
                 }                  }
                 printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst);  
                 err = do_upload(conn, g.gl_pathv[0], abs_dst, pflag);                  err = do_upload(conn, g.gl_pathv[0], abs_dst, pflag);
                 goto out;                  goto out;
         }          }
Line 523 
Line 544 
         }          }
   
         for (i = 0; g.gl_pathv[i]; i++) {          for (i = 0; g.gl_pathv[i]; i++) {
                   if (!is_reg(g.gl_pathv[i])) {
                           error("skipping non-regular file %s",
                               g.gl_pathv[i]);
                           continue;
                   }
                 if (infer_path(g.gl_pathv[i], &tmp)) {                  if (infer_path(g.gl_pathv[i], &tmp)) {
                         err = -1;                          err = -1;
                         goto out;                          goto out;
Line 552 
Line 578 
         SFTP_DIRENT *a = *(SFTP_DIRENT **)aa;          SFTP_DIRENT *a = *(SFTP_DIRENT **)aa;
         SFTP_DIRENT *b = *(SFTP_DIRENT **)bb;          SFTP_DIRENT *b = *(SFTP_DIRENT **)bb;
   
         return (strcmp(a->filename, b->filename));          return (strcmp(a->filename, b->filename));
 }  }
   
 /* sftp ls.1 replacement for directories */  /* sftp ls.1 replacement for directories */
Line 565 
Line 591 
         if ((n = do_readdir(conn, path, &d)) != 0)          if ((n = do_readdir(conn, path, &d)) != 0)
                 return (n);                  return (n);
   
         /* Count entries for sort */          /* Count entries for sort */
         for (n = 0; d[n] != NULL; n++)          for (n = 0; d[n] != NULL; n++)
                 ;                  ;
   
Line 573 
Line 599 
   
         for (n = 0; d[n] != NULL; n++) {          for (n = 0; d[n] != NULL; n++) {
                 char *tmp, *fname;                  char *tmp, *fname;
   
                 tmp = path_append(path, d[n]->filename);                  tmp = path_append(path, d[n]->filename);
                 fname = path_strip(tmp, strip_path);                  fname = path_strip(tmp, strip_path);
                 xfree(tmp);                  xfree(tmp);
Line 591 
Line 617 
                         /* XXX - multicolumn display would be nice here */                          /* XXX - multicolumn display would be nice here */
                         printf("%s\n", fname);                          printf("%s\n", fname);
                 }                  }
   
                 xfree(fname);                  xfree(fname);
         }          }
   
Line 601 
Line 627 
   
 /* sftp ls.1 replacement which handles path globs */  /* sftp ls.1 replacement which handles path globs */
 static int  static int
 do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,  do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
     int lflag)      int lflag)
 {  {
         glob_t g;          glob_t g;
Line 611 
Line 637 
   
         memset(&g, 0, sizeof(g));          memset(&g, 0, sizeof(g));
   
         if (remote_glob(conn, path, GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE,          if (remote_glob(conn, path, GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE,
             NULL, &g)) {              NULL, &g)) {
                 error("Can't ls: \"%s\" not found", path);                  error("Can't ls: \"%s\" not found", path);
                 return (-1);                  return (-1);
         }          }
   
         /*          /*
          * If the glob returns a single match, which is the same as the           * If the glob returns a single match, which is the same as the
          * input glob, and it is a directory, then just list its contents           * input glob, and it is a directory, then just list its contents
          */           */
         if (g.gl_pathc == 1 &&          if (g.gl_pathc == 1 &&
             strncmp(path, g.gl_pathv[0], strlen(g.gl_pathv[0]) - 1) == 0) {              strncmp(path, g.gl_pathv[0], strlen(g.gl_pathv[0]) - 1) == 0) {
                 if ((a = do_lstat(conn, path, 1)) == NULL) {                  if ((a = do_lstat(conn, path, 1)) == NULL) {
                         globfree(&g);                          globfree(&g);
                         return (-1);                          return (-1);
                 }                  }
                 if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&                  if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
                     S_ISDIR(a->perm)) {                      S_ISDIR(a->perm)) {
                         globfree(&g);                          globfree(&g);
                         return (do_ls_dir(conn, path, strip_path, lflag));                          return (do_ls_dir(conn, path, strip_path, lflag));
Line 642 
Line 668 
                 if (lflag) {                  if (lflag) {
                         /*                          /*
                          * XXX: this is slow - 1 roundtrip per path                           * XXX: this is slow - 1 roundtrip per path
                          * A solution to this is to fork glob() and                           * A solution to this is to fork glob() and
                          * build a sftp specific version which keeps the                           * build a sftp specific version which keeps the
                          * attribs (which currently get thrown away)                           * attribs (which currently get thrown away)
                          * that the server returns as well as the filenames.                           * that the server returns as well as the filenames.
                          */                           */
Line 668 
Line 694 
 }  }
   
 static int  static int
 parse_args(const char **cpp, int *pflag, int *lflag,  parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
     unsigned long *n_arg, char **path1, char **path2)      unsigned long *n_arg, char **path1, char **path2)
 {  {
         const char *cmd, *cp = *cpp;          const char *cmd, *cp = *cpp;
Line 680 
Line 706 
         /* Skip leading whitespace */          /* Skip leading whitespace */
         cp = cp + strspn(cp, WHITESPACE);          cp = cp + strspn(cp, WHITESPACE);
   
         /* Ignore blank lines */          /* Ignore blank lines and lines which begin with comment '#' char */
         if (!*cp)          if (*cp == '\0' || *cp == '#')
                 return(-1);                  return (0);
   
           /* Check for leading '-' (disable error processing) */
           *iflag = 0;
           if (*cp == '-') {
                   *iflag = 1;
                   cp++;
           }
   
         /* Figure out which command we have */          /* Figure out which command we have */
         for (i = 0; cmds[i].c; i++) {          for (i = 0; cmds[i].c; i++) {
                 int cmdlen = strlen(cmds[i].c);                  int cmdlen = strlen(cmds[i].c);
Line 705 
Line 738 
                 cmdnum = I_SHELL;                  cmdnum = I_SHELL;
         } else if (cmdnum == -1) {          } else if (cmdnum == -1) {
                 error("Invalid command.");                  error("Invalid command.");
                 return(-1);                  return (-1);
         }          }
   
         /* Get arguments and parse flags */          /* Get arguments and parse flags */
Line 805 
Line 838 
         case I_LPWD:          case I_LPWD:
         case I_HELP:          case I_HELP:
         case I_VERSION:          case I_VERSION:
           case I_PROGRESS:
                 break;                  break;
         default:          default:
                 fatal("Command not implemented");                  fatal("Command not implemented");
Line 815 
Line 849 
 }  }
   
 static int  static int
 parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd)  parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
       int err_abort)
 {  {
         char *path1, *path2, *tmp;          char *path1, *path2, *tmp;
         int pflag, lflag, cmdnum, i;          int pflag, lflag, iflag, cmdnum, i;
         unsigned long n_arg;          unsigned long n_arg;
         Attrib a, *aa;          Attrib a, *aa;
         char path_buf[MAXPATHLEN];          char path_buf[MAXPATHLEN];
Line 826 
Line 861 
         glob_t g;          glob_t g;
   
         path1 = path2 = NULL;          path1 = path2 = NULL;
         cmdnum = parse_args(&cmd, &pflag, &lflag, &n_arg,          cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg,
             &path1, &path2);              &path1, &path2);
   
           if (iflag != 0)
                   err_abort = 0;
   
         memset(&g, 0, sizeof(g));          memset(&g, 0, sizeof(g));
   
         /* Perform command */          /* Perform command */
         switch (cmdnum) {          switch (cmdnum) {
           case 0:
                   /* Blank line */
                   break;
         case -1:          case -1:
                   /* Unrecognized command */
                   err = -1;
                 break;                  break;
         case I_GET:          case I_GET:
                 err = process_get(conn, path1, path2, *pwd, pflag);                  err = process_get(conn, path1, path2, *pwd, pflag);
Line 855 
Line 898 
                 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);                  remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
                 for (i = 0; g.gl_pathv[i]; i++) {                  for (i = 0; g.gl_pathv[i]; i++) {
                         printf("Removing %s\n", g.gl_pathv[i]);                          printf("Removing %s\n", g.gl_pathv[i]);
                         if (do_rm(conn, g.gl_pathv[i]) == -1)                          err = do_rm(conn, g.gl_pathv[i]);
                                 err = -1;                          if (err != 0 && err_abort)
                                   break;
                 }                  }
                 break;                  break;
         case I_MKDIR:          case I_MKDIR:
Line 902 
Line 946 
                         do_globbed_ls(conn, *pwd, *pwd, lflag);                          do_globbed_ls(conn, *pwd, *pwd, lflag);
                         break;                          break;
                 }                  }
   
                 /* Strip pwd off beginning of non-absolute paths */                  /* Strip pwd off beginning of non-absolute paths */
                 tmp = NULL;                  tmp = NULL;
                 if (*path1 != '/')                  if (*path1 != '/')
                         tmp = *pwd;                          tmp = *pwd;
   
                 path1 = make_absolute(path1, *pwd);                  path1 = make_absolute(path1, *pwd);
                   err = do_globbed_ls(conn, path1, tmp, lflag);
                 do_globbed_ls(conn, path1, tmp, lflag);  
                 break;                  break;
         case I_LCHDIR:          case I_LCHDIR:
                 if (chdir(path1) == -1) {                  if (chdir(path1) == -1) {
Line 944 
Line 987 
                 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);                  remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
                 for (i = 0; g.gl_pathv[i]; i++) {                  for (i = 0; g.gl_pathv[i]; i++) {
                         printf("Changing mode on %s\n", g.gl_pathv[i]);                          printf("Changing mode on %s\n", g.gl_pathv[i]);
                         do_setstat(conn, g.gl_pathv[i], &a);                          err = do_setstat(conn, g.gl_pathv[i], &a);
                           if (err != 0 && err_abort)
                                   break;
                 }                  }
                 break;                  break;
         case I_CHOWN:          case I_CHOWN:
                 path1 = make_absolute(path1, *pwd);  
                 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);  
                 for (i = 0; g.gl_pathv[i]; i++) {  
                         if (!(aa = do_stat(conn, g.gl_pathv[i], 0)))  
                                 continue;  
                         if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {  
                                 error("Can't get current ownership of "  
                                     "remote file \"%s\"", g.gl_pathv[i]);  
                                 continue;  
                         }  
                         printf("Changing owner on %s\n", g.gl_pathv[i]);  
                         aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;  
                         aa->uid = n_arg;  
                         do_setstat(conn, g.gl_pathv[i], aa);  
                 }  
                 break;  
         case I_CHGRP:          case I_CHGRP:
                 path1 = make_absolute(path1, *pwd);                  path1 = make_absolute(path1, *pwd);
                 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);                  remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
                 for (i = 0; g.gl_pathv[i]; i++) {                  for (i = 0; g.gl_pathv[i]; i++) {
                         if (!(aa = do_stat(conn, g.gl_pathv[i], 0)))                          if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) {
                                 continue;                                  if (err != 0 && err_abort)
                                           break;
                                   else
                                           continue;
                           }
                         if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {                          if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
                                 error("Can't get current ownership of "                                  error("Can't get current ownership of "
                                     "remote file \"%s\"", g.gl_pathv[i]);                                      "remote file \"%s\"", g.gl_pathv[i]);
                                 continue;                                  if (err != 0 && err_abort)
                                           break;
                                   else
                                           continue;
                         }                          }
                         printf("Changing group on %s\n", g.gl_pathv[i]);  
                         aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;                          aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
                         aa->gid = n_arg;                          if (cmdnum == I_CHOWN) {
                         do_setstat(conn, g.gl_pathv[i], aa);                                  printf("Changing owner on %s\n", g.gl_pathv[i]);
                                   aa->uid = n_arg;
                           } else {
                                   printf("Changing group on %s\n", g.gl_pathv[i]);
                                   aa->gid = n_arg;
                           }
                           err = do_setstat(conn, g.gl_pathv[i], aa);
                           if (err != 0 && err_abort)
                                   break;
                 }                  }
                 break;                  break;
         case I_PWD:          case I_PWD:
                 printf("Remote working directory: %s\n", *pwd);                  printf("Remote working directory: %s\n", *pwd);
                 break;                  break;
         case I_LPWD:          case I_LPWD:
                 if (!getcwd(path_buf, sizeof(path_buf)))                  if (!getcwd(path_buf, sizeof(path_buf))) {
                         error("Couldn't get local cwd: %s",                          error("Couldn't get local cwd: %s", strerror(errno));
                             strerror(errno));                          err = -1;
                 else                          break;
                         printf("Local working directory: %s\n",                  }
                             path_buf);                  printf("Local working directory: %s\n", path_buf);
                 break;                  break;
         case I_QUIT:          case I_QUIT:
                 return(-1);                  /* Processed below */
                   break;
         case I_HELP:          case I_HELP:
                 help();                  help();
                 break;                  break;
         case I_VERSION:          case I_VERSION:
                 printf("SFTP protocol version %u\n", sftp_proto_version(conn));                  printf("SFTP protocol version %u\n", sftp_proto_version(conn));
                 break;                  break;
           case I_PROGRESS:
                   showprogress = !showprogress;
                   if (showprogress)
                           printf("Progress meter enabled\n");
                   else
                           printf("Progress meter disabled\n");
                   break;
         default:          default:
                 fatal("%d is not implemented", cmdnum);                  fatal("%d is not implemented", cmdnum);
         }          }
Line 1011 
Line 1062 
         if (path2)          if (path2)
                 xfree(path2);                  xfree(path2);
   
         /* If an error occurs in batch mode we should abort. */          /* If an unignored error occurs in batch mode we should abort. */
         if (infile != stdin && err > 0)          if (err_abort && err != 0)
                 return -1;                  return (-1);
           else if (cmdnum == I_QUIT)
                   return (1);
   
         return(0);          return (0);
 }  }
   
 void  int
 interactive_loop(int fd_in, int fd_out, char *file1, char *file2)  interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
 {  {
         char *pwd;          char *pwd;
         char *dir = NULL;          char *dir = NULL;
         char cmd[2048];          char cmd[2048];
         struct sftp_conn *conn;          struct sftp_conn *conn;
           int err;
   
         conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests);          conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests);
         if (conn == NULL)          if (conn == NULL)
Line 1041 
Line 1095 
                 if (remote_is_dir(conn, dir) && file2 == NULL) {                  if (remote_is_dir(conn, dir) && file2 == NULL) {
                         printf("Changing to: %s\n", dir);                          printf("Changing to: %s\n", dir);
                         snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);                          snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
                         parse_dispatch_command(conn, cmd, &pwd);                          if (parse_dispatch_command(conn, cmd, &pwd, 1) != 0)
                                   return (-1);
                 } else {                  } else {
                         if (file2 == NULL)                          if (file2 == NULL)
                                 snprintf(cmd, sizeof cmd, "get %s", dir);                                  snprintf(cmd, sizeof cmd, "get %s", dir);
Line 1049 
Line 1104 
                                 snprintf(cmd, sizeof cmd, "get %s %s", dir,                                  snprintf(cmd, sizeof cmd, "get %s %s", dir,
                                     file2);                                      file2);
   
                         parse_dispatch_command(conn, cmd, &pwd);                          err = parse_dispatch_command(conn, cmd, &pwd, 1);
                         xfree(dir);                          xfree(dir);
                         return;                          xfree(pwd);
                           return (err);
                 }                  }
                 xfree(dir);                  xfree(dir);
         }          }
   
         setvbuf(stdout, NULL, _IOLBF, 0);          setvbuf(stdout, NULL, _IOLBF, 0);
         setvbuf(infile, NULL, _IOLBF, 0);          setvbuf(infile, NULL, _IOLBF, 0);
   
           err = 0;
         for (;;) {          for (;;) {
                 char *cp;                  char *cp;
   
Line 1074 
Line 1132 
                 if (cp)                  if (cp)
                         *cp = '\0';                          *cp = '\0';
   
                 if (parse_dispatch_command(conn, cmd, &pwd))                  err = parse_dispatch_command(conn, cmd, &pwd, infile != stdin);
                   if (err != 0)
                         break;                          break;
         }          }
         xfree(pwd);          xfree(pwd);
   
           /* err == 1 signifies normal "quit" exit */
           return (err >= 0 ? 0 : -1);
 }  }
   

Legend:
Removed from v.1.49  
changed lines
  Added in v.1.49.2.1