[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.2.2 and 1.50

version 1.49.2.2, 2003/09/16 21:20:27 version 1.50, 2002/11/21 23:03:51
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"
   
 /* Define what type of ls view (0 - multi-column) */  
 #define LONG_VIEW 1             /* Full view ala ls -l */  
 #define SHORT_VIEW 2            /* Single row view ala ls -1 */  
   
 /* Commands for interactive mode */  /* Commands for interactive mode */
 #define I_CHDIR         1  #define I_CHDIR         1
 #define I_CHGRP         2  #define I_CHGRP         2
Line 82 
Line 75 
 #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;
 };  };
   
 static const struct CMD cmds[] = {  const struct CMD cmds[] = {
         { "bye",        I_QUIT },          { "bye",        I_QUIT },
         { "cd",         I_CHDIR },          { "cd",         I_CHDIR },
         { "chdir",      I_CHDIR },          { "chdir",      I_CHDIR },
Line 110 
Line 102 
         { "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 143 
Line 134 
         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 313 
Line 303 
                 for(; strchr(WHITESPACE, *cp) == NULL; cp++) {                  for(; strchr(WHITESPACE, *cp) == NULL; cp++) {
                         switch (*cp) {                          switch (*cp) {
                         case 'l':                          case 'l':
                                 *lflag = LONG_VIEW;                                  *lflag = 1;
                                 break;                                  break;
                         case '1':  
                                 *lflag = SHORT_VIEW;  
                                 break;  
                         default:                          default:
                                 error("Invalid flag -%c", *cp);                                  error("Invalid flag -%c", *cp);
                                 return(-1);                                  return(-1);
Line 334 
Line 321 
 {  {
         const char *cp = *cpp, *end;          const char *cp = *cpp, *end;
         char quot;          char quot;
         int i, j;          int i;
   
         cp += strspn(cp, WHITESPACE);          cp += strspn(cp, WHITESPACE);
         if (!*cp) {          if (!*cp) {
Line 343 
Line 330 
                 return (0);                  return (0);
         }          }
   
         *path = xmalloc(strlen(cp) + 1);  
   
         /* Check for quoted filenames */          /* Check for quoted filenames */
         if (*cp == '\"' || *cp == '\'') {          if (*cp == '\"' || *cp == '\'') {
                 quot = *cp++;                  quot = *cp++;
   
                 /* Search for terminating quote, unescape some chars */                  end = strchr(cp, quot);
                 for (i = j = 0; i <= strlen(cp); i++) {                  if (end == NULL) {
                         if (cp[i] == quot) {    /* Found quote */                          error("Unterminated quote");
                                 (*path)[j] = '\0';                          goto fail;
                                 break;  
                         }  
                         if (cp[i] == '\0') {    /* End of string */  
                                 error("Unterminated quote");  
                                 goto fail;  
                         }  
                         if (cp[i] == '\\') {    /* Escaped characters */  
                                 i++;  
                                 if (cp[i] != '\'' && cp[i] != '\"' &&  
                                     cp[i] != '\\') {  
                                         error("Bad escaped character '\%c'",  
                                             cp[i]);  
                                         goto fail;  
                                 }  
                         }  
                         (*path)[j++] = cp[i];  
                 }                  }
                   if (cp == end) {
                 if (j == 0) {  
                         error("Empty quotes");                          error("Empty quotes");
                         goto fail;                          goto fail;
                 }                  }
                 *cpp = cp + i + strspn(cp + i, WHITESPACE);                  *cpp = end + 1 + strspn(end + 1, WHITESPACE);
         } else {          } else {
                 /* Read to end of filename */                  /* Read to end of filename */
                 end = strpbrk(cp, WHITESPACE);                  end = strpbrk(cp, WHITESPACE);
                 if (end == NULL)                  if (end == NULL)
                         end = strchr(cp, '\0');                          end = strchr(cp, '\0');
                 *cpp = end + strspn(end, WHITESPACE);                  *cpp = end + strspn(end, WHITESPACE);
   
                 memcpy(*path, cp, end - cp);  
                 (*path)[end - cp] = '\0';  
         }          }
         return (0);  
   
           i = end - cp;
   
           *path = xmalloc(i + 1);
           memcpy(*path, cp, i);
           (*path)[i] = '\0';
           return(0);
   
  fail:   fail:
         xfree(*path);          *path = NULL;
         *path = NULL;  
         return (-1);          return (-1);
 }  }
   
Line 407 
Line 377 
 }  }
   
 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 451 
Line 410 
                 goto out;                  goto out;
         }          }
   
         /* If multiple matches, dst must be a directory or unspecified */          /* Only one match, dst may be file, directory or unspecified */
         if (g.gl_matchc > 1 && dst && !is_dir(dst)) {          if (g.gl_pathv[0] && g.gl_matchc == 1) {
                   if (dst) {
                           /* If directory specified, append filename */
                           if (is_dir(dst)) {
                                   if (infer_path(g.gl_pathv[0], &tmp)) {
                                           err = 1;
                                           goto out;
                                   }
                                   abs_dst = path_append(dst, tmp);
                                   xfree(tmp);
                           } else
                                   abs_dst = xstrdup(dst);
                   } else if (infer_path(g.gl_pathv[0], &abs_dst)) {
                           err = -1;
                           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);
                   goto out;
           }
   
           /* Multiple matches, dst may be directory or unspecified */
           if (dst && !is_dir(dst)) {
                 error("Multiple files match, but \"%s\" is not a directory",                  error("Multiple files match, but \"%s\" is not a directory",
                     dst);                      dst);
                 err = -1;                  err = -1;
Line 464 
Line 445 
                         err = -1;                          err = -1;
                         goto out;                          goto out;
                 }                  }
                   if (dst) {
                 if (g.gl_matchc == 1 && dst) {  
                         /* If directory specified, append filename */  
                         if (is_dir(dst)) {  
                                 if (infer_path(g.gl_pathv[0], &tmp)) {  
                                         err = 1;  
                                         goto out;  
                                 }  
                                 abs_dst = path_append(dst, tmp);  
                                 xfree(tmp);  
                         } else  
                                 abs_dst = xstrdup(dst);  
                 } else if (dst) {  
                         abs_dst = path_append(dst, tmp);                          abs_dst = path_append(dst, tmp);
                         xfree(tmp);                          xfree(tmp);
                 } else                  } else
Line 520 
Line 489 
                 goto out;                  goto out;
         }          }
   
         /* If multiple matches, dst may be directory or unspecified */          /* Only one match, dst may be file, directory or unspecified */
         if (g.gl_matchc > 1 && tmp_dst && !remote_is_dir(conn, tmp_dst)) {          if (g.gl_pathv[0] && g.gl_matchc == 1) {
                 error("Multiple files match, but \"%s\" is not a directory",                  if (tmp_dst) {
                     tmp_dst);  
                 err = -1;  
                 goto out;  
         }  
   
         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)) {  
                         err = -1;  
                         goto out;  
                 }  
   
                 if (g.gl_matchc == 1 && 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)) {
                                 if (infer_path(g.gl_pathv[0], &tmp)) {                                  if (infer_path(g.gl_pathv[0], &tmp)) {
Line 550 
Line 502 
                                 xfree(tmp);                                  xfree(tmp);
                         } else                          } else
                                 abs_dst = xstrdup(tmp_dst);                                  abs_dst = xstrdup(tmp_dst);
                   } else {
                           if (infer_path(g.gl_pathv[0], &abs_dst)) {
                                   err = -1;
                                   goto out;
                           }
                           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);
                   goto out;
           }
   
                 } else if (tmp_dst) {          /* Multiple matches, dst may be directory or unspecified */
           if (tmp_dst && !remote_is_dir(conn, tmp_dst)) {
                   error("Multiple files match, but \"%s\" is not a directory",
                       tmp_dst);
                   err = -1;
                   goto out;
           }
   
           for (i = 0; g.gl_pathv[i]; i++) {
                   if (infer_path(g.gl_pathv[i], &tmp)) {
                           err = -1;
                           goto out;
                   }
                   if (tmp_dst) {
                         abs_dst = path_append(tmp_dst, tmp);                          abs_dst = path_append(tmp_dst, tmp);
                         xfree(tmp);                          xfree(tmp);
                 } else                  } else
Line 567 
Line 543 
                 xfree(abs_dst);                  xfree(abs_dst);
         if (tmp_dst)          if (tmp_dst)
                 xfree(tmp_dst);                  xfree(tmp_dst);
         globfree(&g);  
         return(err);          return(err);
 }  }
   
Line 584 
Line 559 
 static int  static int
 do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)  do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
 {  {
         int n, c = 1, colspace = 0, columns = 1;          int n;
         SFTP_DIRENT **d;          SFTP_DIRENT **d;
   
         if ((n = do_readdir(conn, path, &d)) != 0)          if ((n = do_readdir(conn, path, &d)) != 0)
                 return (n);                  return (n);
   
         if (!(lflag & SHORT_VIEW)) {          /* Count entries for sort */
                 int m = 0, width = 80;          for (n = 0; d[n] != NULL; n++)
                 struct winsize ws;                  ;
   
                 /* Count entries for sort and find longest filename */  
                 for (n = 0; d[n] != NULL; n++)  
                         m = MAX(m, strlen(d[n]->filename));  
   
                 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)  
                         width = ws.ws_col;  
   
                 columns = width / (m + 2);  
                 columns = MAX(columns, 1);  
                 colspace = width / columns;  
         }  
   
         qsort(d, n, sizeof(*d), sdirent_comp);          qsort(d, n, sizeof(*d), sdirent_comp);
   
         for (n = 0; d[n] != NULL; n++) {          for (n = 0; d[n] != NULL; n++) {
Line 615 
Line 578 
                 fname = path_strip(tmp, strip_path);                  fname = path_strip(tmp, strip_path);
                 xfree(tmp);                  xfree(tmp);
   
                 if (lflag & LONG_VIEW) {                  if (lflag) {
                         char *lname;                          char *lname;
                         struct stat sb;                          struct stat sb;
   
Line 625 
Line 588 
                         printf("%s\n", lname);                          printf("%s\n", lname);
                         xfree(lname);                          xfree(lname);
                 } else {                  } else {
                         printf("%-*s", colspace, fname);                          /* XXX - multicolumn display would be nice here */
                         if (c >= columns) {                          printf("%s\n", fname);
                                 printf("\n");  
                                 c = 1;  
                         } else  
                                 c++;  
                 }                  }
   
                 xfree(fname);                  xfree(fname);
         }          }
   
         if (!(lflag & LONG_VIEW) && (c != 1))  
                 printf("\n");  
   
         free_sftp_dirents(d);          free_sftp_dirents(d);
         return (0);          return (0);
 }  }
Line 649 
Line 605 
     int lflag)      int lflag)
 {  {
         glob_t g;          glob_t g;
         int i, c = 1, colspace = 0, columns = 1;          int i;
         Attrib *a;          Attrib *a;
           struct stat sb;
   
         memset(&g, 0, sizeof(g));          memset(&g, 0, sizeof(g));
   
Line 677 
Line 634 
                 }                  }
         }          }
   
         if (!(lflag & SHORT_VIEW)) {  
                 int m = 0, width = 80;  
                 struct winsize ws;  
   
                 /* Count entries for sort and find longest filename */  
                 for (i = 0; g.gl_pathv[i]; i++)  
                         m = MAX(m, strlen(g.gl_pathv[i]));  
   
                 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)  
                         width = ws.ws_col;  
   
                 columns = width / (m + 2);  
                 columns = MAX(columns, 1);  
                 colspace = width / columns;  
         }  
   
         for (i = 0; g.gl_pathv[i]; i++) {          for (i = 0; g.gl_pathv[i]; i++) {
                 char *fname;                  char *fname, *lname;
   
                 fname = path_strip(g.gl_pathv[i], strip_path);                  fname = path_strip(g.gl_pathv[i], strip_path);
   
                 if (lflag & LONG_VIEW) {                  if (lflag) {
                         char *lname;  
                         struct stat sb;  
   
                         /*                          /*
                          * 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
Line 717 
Line 655 
                         printf("%s\n", lname);                          printf("%s\n", lname);
                         xfree(lname);                          xfree(lname);
                 } else {                  } else {
                         printf("%-*s", colspace, fname);                          /* XXX - multicolumn display would be nice here */
                         if (c >= columns) {                          printf("%s\n", fname);
                                 printf("\n");  
                                 c = 1;  
                         } else  
                                 c++;  
                 }                  }
                 xfree(fname);                  xfree(fname);
         }          }
   
         if (!(lflag & LONG_VIEW) && (c != 1))  
                 printf("\n");  
   
         if (g.gl_pathc)          if (g.gl_pathc)
                 globfree(&g);                  globfree(&g);
   
Line 737 
Line 668 
 }  }
   
 static int  static int
 parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,  parse_args(const char **cpp, int *pflag, int *lflag,
     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 749 
Line 680 
         /* Skip leading whitespace */          /* Skip leading whitespace */
         cp = cp + strspn(cp, WHITESPACE);          cp = cp + strspn(cp, WHITESPACE);
   
         /* Ignore blank lines and lines which begin with comment '#' char */          /* Ignore blank lines */
         if (*cp == '\0' || *cp == '#')          if (!*cp)
                 return (0);                  return(-1);
   
         /* 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 781 
Line 705 
                 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 881 
Line 805 
         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 892 
Line 815 
 }  }
   
 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, iflag, cmdnum, i;          int pflag, lflag, 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 904 
Line 826 
         glob_t g;          glob_t g;
   
         path1 = path2 = NULL;          path1 = path2 = NULL;
         cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg,          cmdnum = parse_args(&cmd, &pflag, &lflag, &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 941 
Line 855 
                 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]);
                         err = do_rm(conn, g.gl_pathv[i]);                          if (do_rm(conn, g.gl_pathv[i]) == -1)
                         if (err != 0 && err_abort)                                  err = -1;
                                 break;  
                 }                  }
                 break;                  break;
         case I_MKDIR:          case I_MKDIR:
Line 996 
Line 909 
                         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 1030 
Line 944 
                 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]);
                         err = do_setstat(conn, g.gl_pathv[i], &a);                          do_setstat(conn, g.gl_pathv[i], &a);
                         if (err != 0 && err_abort)  
                                 break;  
                 }                  }
                 break;                  break;
         case I_CHOWN:          case I_CHOWN:
         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)))
                                 if (err != 0 && err_abort)                                  continue;
                                         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]);
                                 if (err != 0 && err_abort)                                  continue;
                                         break;  
                                 else  
                                         continue;  
                         }                          }
                           printf("Changing owner on %s\n", g.gl_pathv[i]);
                         aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;                          aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
                         if (cmdnum == I_CHOWN) {                          aa->uid = n_arg;
                                 printf("Changing owner on %s\n", g.gl_pathv[i]);                          do_setstat(conn, g.gl_pathv[i], aa);
                                 aa->uid = n_arg;                  }
                         } else {                  break;
                                 printf("Changing group on %s\n", g.gl_pathv[i]);          case I_CHGRP:
                                 aa->gid = n_arg;                  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;
                         }                          }
                         err = do_setstat(conn, g.gl_pathv[i], aa);                          printf("Changing group on %s\n", g.gl_pathv[i]);
                         if (err != 0 && err_abort)                          aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
                                 break;                          aa->gid = n_arg;
                           do_setstat(conn, g.gl_pathv[i], aa);
                 }                  }
                 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", strerror(errno));                          error("Couldn't get local cwd: %s",
                         err = -1;                              strerror(errno));
                         break;                  else
                 }                          printf("Local working directory: %s\n",
                 printf("Local working directory: %s\n", path_buf);                              path_buf);
                 break;                  break;
         case I_QUIT:          case I_QUIT:
                 /* Processed below */                  return(-1);
                 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 1105 
Line 1011 
         if (path2)          if (path2)
                 xfree(path2);                  xfree(path2);
   
         /* If an unignored error occurs in batch mode we should abort. */          /* If an error occurs in batch mode we should abort. */
         if (err_abort && err != 0)          if (infile != stdin && err > 0)
                 return (-1);                  return -1;
         else if (cmdnum == I_QUIT)  
                 return (1);  
   
         return (0);          return(0);
 }  }
   
 int  void
 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 1138 
Line 1041 
                 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);
                         if (parse_dispatch_command(conn, cmd, &pwd, 1) != 0)                          parse_dispatch_command(conn, cmd, &pwd);
                                 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 1147 
Line 1049 
                                 snprintf(cmd, sizeof cmd, "get %s %s", dir,                                  snprintf(cmd, sizeof cmd, "get %s %s", dir,
                                     file2);                                      file2);
   
                         err = parse_dispatch_command(conn, cmd, &pwd, 1);                          parse_dispatch_command(conn, cmd, &pwd);
                         xfree(dir);                          xfree(dir);
                         xfree(pwd);                          return;
                         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 1175 
Line 1074 
                 if (cp)                  if (cp)
                         *cp = '\0';                          *cp = '\0';
   
                 err = parse_dispatch_command(conn, cmd, &pwd, infile != stdin);                  if (parse_dispatch_command(conn, cmd, &pwd))
                 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.2.2  
changed lines
  Added in v.1.50