]> andersk Git - openssh.git/commitdiff
- (djm) Sync sftp and scp stuff from OpenBSD:
authordjm <djm>
Fri, 9 Feb 2001 13:40:03 +0000 (13:40 +0000)
committerdjm <djm>
Fri, 9 Feb 2001 13:40:03 +0000 (13:40 +0000)
   - djm@cvs.openbsd.org     2001/02/07 03:55:13
     [sftp-client.c]
     Don't free handles before we are done with them. Based on work from
     Corinna Vinschen <vinschen@redhat.com>. ok markus@
   - djm@cvs.openbsd.org     2001/02/06 22:32:53
     [sftp.1]
     Punctuation fix from Pekka Savola <pekkas@netcore.fi>
   - deraadt@cvs.openbsd.org 2001/02/07 04:07:29
     [sftp.1]
     pretty up significantly
   - itojun@cvs.openbsd.org  2001/02/07 06:49:42
     [sftp.1]
     .Bl-.El mismatch.  markus ok
   - djm@cvs.openbsd.org     2001/02/07 06:12:30
     [sftp-int.c]
     Check that target is a directory before doing ls; ok markus@
   - itojun@cvs.openbsd.org  2001/02/07 11:01:18
     [scp.c sftp-client.c sftp-server.c]
     unsigned long long -> %llu, not %qu.  markus ok
   - stevesk@cvs.openbsd.org 2001/02/07 11:10:39
     [sftp.1 sftp-int.c]
     more man page cleanup and sync of help text with man page; ok markus@
   - markus@cvs.openbsd.org  2001/02/07 14:58:34
     [sftp-client.c]
     older servers reply with SSH2_FXP_NAME + count==0 instead of EOF
   - djm@cvs.openbsd.org     2001/02/07 15:27:19
     [sftp.c]
     Don't forward agent and X11 in sftp. Suggestion from Roumen Petrov
     <roumen.petrov@skalasoft.com>
   - stevesk@cvs.openbsd.org 2001/02/07 15:36:04
     [sftp-int.c]
     portable; ok markus@
   - stevesk@cvs.openbsd.org 2001/02/07 15:55:47
     [sftp-int.c]
     lowercase cmds[].c also; ok markus@
   - markus@cvs.openbsd.org  2001/02/07 17:04:52
     [pathnames.h sftp.c]
     allow sftp over ssh protocol 1; ok djm@
   - deraadt@cvs.openbsd.org 2001/02/08 07:38:55
     [scp.c]
     memory leak fix, and snprintf throughout
   - deraadt@cvs.openbsd.org 2001/02/08 08:02:02
     [sftp-int.c]
     plug a memory leak
   - stevesk@cvs.openbsd.org 2001/02/08 10:11:23
     [session.c sftp-client.c]
     %i -> %d
   - stevesk@cvs.openbsd.org 2001/02/08 10:57:59
     [sftp-int.c]
     typo
   - stevesk@cvs.openbsd.org 2001/02/08 15:28:07
     [sftp-int.c pathnames.h]
     _PATH_LS; ok markus@
   - djm@cvs.openbsd.org     2001/02/09 04:46:25
     [sftp-int.c]
     Check for NULL attribs for chown, chmod & chgrp operations, only send
     relevant attribs back to server; ok markus@
 - (djm) Update makefile.in for _PATH_SFTP_SERVER

ChangeLog
Makefile.in
pathnames.h
sftp-client.c
sftp-common.c
sftp-int.c
sftp.1
sftp.c

index 42f6248c9011d4663993f289d6e98f4c3cdf974c..fab9bc8c777b9ebcaa0f82c372a72c1917b3fae3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,67 @@
+20010210
+ - (djm) Sync sftp and scp stuff from OpenBSD:
+   - djm@cvs.openbsd.org     2001/02/07 03:55:13
+     [sftp-client.c]
+     Don't free handles before we are done with them. Based on work from
+     Corinna Vinschen <vinschen@redhat.com>. ok markus@
+   - djm@cvs.openbsd.org     2001/02/06 22:32:53
+     [sftp.1]
+     Punctuation fix from Pekka Savola <pekkas@netcore.fi>
+   - deraadt@cvs.openbsd.org 2001/02/07 04:07:29
+     [sftp.1]
+     pretty up significantly
+   - itojun@cvs.openbsd.org  2001/02/07 06:49:42
+     [sftp.1]
+     .Bl-.El mismatch.  markus ok
+   - djm@cvs.openbsd.org     2001/02/07 06:12:30
+     [sftp-int.c]
+     Check that target is a directory before doing ls; ok markus@
+   - itojun@cvs.openbsd.org  2001/02/07 11:01:18
+     [scp.c sftp-client.c sftp-server.c]
+     unsigned long long -> %llu, not %qu.  markus ok
+   - stevesk@cvs.openbsd.org 2001/02/07 11:10:39
+     [sftp.1 sftp-int.c]
+     more man page cleanup and sync of help text with man page; ok markus@
+   - markus@cvs.openbsd.org  2001/02/07 14:58:34
+     [sftp-client.c]
+     older servers reply with SSH2_FXP_NAME + count==0 instead of EOF
+   - djm@cvs.openbsd.org     2001/02/07 15:27:19
+     [sftp.c]
+     Don't forward agent and X11 in sftp. Suggestion from Roumen Petrov
+     <roumen.petrov@skalasoft.com>
+   - stevesk@cvs.openbsd.org 2001/02/07 15:36:04
+     [sftp-int.c]
+     portable; ok markus@
+   - stevesk@cvs.openbsd.org 2001/02/07 15:55:47
+     [sftp-int.c]
+     lowercase cmds[].c also; ok markus@
+   - markus@cvs.openbsd.org  2001/02/07 17:04:52
+     [pathnames.h sftp.c]
+     allow sftp over ssh protocol 1; ok djm@
+   - deraadt@cvs.openbsd.org 2001/02/08 07:38:55
+     [scp.c]
+     memory leak fix, and snprintf throughout
+   - deraadt@cvs.openbsd.org 2001/02/08 08:02:02
+     [sftp-int.c]
+     plug a memory leak
+   - stevesk@cvs.openbsd.org 2001/02/08 10:11:23
+     [session.c sftp-client.c]
+     %i -> %d
+   - stevesk@cvs.openbsd.org 2001/02/08 10:57:59
+     [sftp-int.c]
+     typo
+   - stevesk@cvs.openbsd.org 2001/02/08 15:28:07
+     [sftp-int.c pathnames.h]
+     _PATH_LS; ok markus@
+   - djm@cvs.openbsd.org     2001/02/09 04:46:25
+     [sftp-int.c]
+     Check for NULL attribs for chown, chmod & chgrp operations, only send
+     relevant attribs back to server; ok markus@
+ - (djm) Update makefile.in for _PATH_SFTP_SERVER
+
+
+
+
 20010209
  - (bal) patch to vis.c to deal with HAVE_VIS right by Robert Mooney 
    <rjmooney@mediaone.net>
index 74610874854773cb168eb0942dcdba5019352f9d..4f7d1d74e9483900860b73b00bb853be1979d89c 100644 (file)
@@ -16,10 +16,15 @@ DESTDIR=
 VPATH=@srcdir@
 SSH_PROGRAM=@bindir@/ssh
 ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
+SFTP_SERVER=$(libexecdir)/sftp-server
+
+PATHS= -DETCDIR=\"$(sysconfdir)\" \
+       -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \
+       -D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \
+       -D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\"
 
 CC=@CC@
 LD=@LD@
-PATHS=-DETCDIR=\"$(sysconfdir)\" -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" -D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\"
 CFLAGS=@CFLAGS@
 CPPFLAGS=@CPPFLAGS@ -I. -I$(srcdir)/openbsd-compat -I$(srcdir) $(PATHS) @DEFS@
 LIBS=@LIBS@
@@ -162,7 +167,7 @@ install-files:
        $(INSTALL) -m 0775 -s ssh-keyscan $(DESTDIR)$(bindir)/ssh-keyscan
        $(INSTALL) -m 0755 -s sshd $(DESTDIR)$(sbindir)/sshd
        @NO_SFTP@$(INSTALL) -m 0755 -s sftp $(DESTDIR)$(bindir)/sftp
-       @NO_SFTP@$(INSTALL) -m 0755 -s sftp-server $(DESTDIR)$(libexecdir)/sftp-server
+       @NO_SFTP@$(INSTALL) -m 0755 -s sftp-server $(DESTDIR)$(SFTP_SERVER)
        $(INSTALL) -m 644 ssh.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
        $(INSTALL) -m 644 scp.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
        $(INSTALL) -m 644 ssh-add.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
@@ -250,7 +255,7 @@ uninstall:
        -rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
        -rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
        -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
-       -rm -r $(DESTDIR)$(libexecdir)/sftp-server$(EXEEXT)
+       -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
index 85d8a1fe2388da468970430437e2a490a81c7ad1..3f116bdbb68524fc4df824a1fe4edc8a29c377b8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pathnames.h,v 1.2 2001/01/29 01:58:17 niklas Exp $    */
+/*     $OpenBSD: pathnames.h,v 1.4 2001/02/08 22:28:07 stevesk Exp $   */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
 #define _PATH_CP                       "cp"
 #endif
 
+/* for sftp */
+#ifndef _PATH_SFTP_SERVER
+#define _PATH_SFTP_SERVER              "/usr/libexec/sftp-server"
+#endif
+#define _PATH_LS                       "ls"
+
 /* path to login program */
 #ifndef LOGIN_PROGRAM
 # ifdef LOGIN_PROGRAM_FALLBACK
index e8b9007fecad45e38580bd87a997fd139020522a..490c00bdd866f71a4b49123025f17b71c5636aa3 100644 (file)
@@ -29,7 +29,7 @@
 /* XXX: copy between two remote sites */
 
 #include "includes.h"
-RCSID("$OpenBSD: sftp-client.c,v 1.4 2001/02/06 23:30:28 djm Exp $");
+RCSID("$OpenBSD: sftp-client.c,v 1.8 2001/02/08 17:11:23 stevesk Exp $");
 
 #include "ssh.h"
 #include "buffer.h"
@@ -338,7 +338,9 @@ do_ls(int fd_in, int fd_out, char *path)
                            SSH2_FXP_NAME, type);
 
                count = buffer_get_int(&msg);
-               debug3("Received %i SSH2_FXP_NAME responses", count);
+               if (count == 0)
+                       break;
+               debug3("Received %d SSH2_FXP_NAME responses", count);
                for(i = 0; i < count; i++) {
                        char *filename, *longname;
                        Attrib *a;
@@ -556,6 +558,7 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
        char *handle;
        Buffer msg;
        Attrib junk, *a;
+       int status;
 
        a = do_stat(fd_in, fd_out, remote_path);
        if (a == NULL)
@@ -635,7 +638,7 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
                if (id != expected_id)
                        fatal("ID mismatch (%d != %d)", id, expected_id);
                if (type == SSH2_FXP_STATUS) {
-                       int status = buffer_get_int(&msg);
+                       status = buffer_get_int(&msg);
 
                        if (status == SSH2_FX_EOF)
                                break;
@@ -644,10 +647,7 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
                                    "file \"%s\" : %s", remote_path,
                                     fx2txt(status));
                                do_close(fd_in, fd_out, handle, handle_len);
-                               xfree(handle);
-                               close(local_fd);
-                               buffer_free(&msg);
-                               return(status);
+                               goto done;
                        }
                } else if (type != SSH2_FXP_DATA) {
                        fatal("Expected SSH2_FXP_DATA(%d) packet, got %d",
@@ -659,27 +659,27 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
                        fatal("Received more data than asked for %d > %d",
                            len, COPY_SIZE);
 
-               debug3("In read loop, got %d offset %lld", len,
+               debug3("In read loop, got %d offset %llu", len,
                    (unsigned long long)offset);
                if (atomicio(write, local_fd, data, len) != len) {
                        error("Couldn't write to \"%s\": %s", local_path,
                            strerror(errno));
                        do_close(fd_in, fd_out, handle, handle_len);
-                       xfree(handle);
-                       close(local_fd);
+                       status = -1;
                        xfree(data);
-                       buffer_free(&msg);
-                       return(-1);
+                       goto done;
                }
 
                offset += len;
                xfree(data);
        }
-       xfree(handle);
-       buffer_free(&msg);
-       close(local_fd);
+       status = do_close(fd_in, fd_out, handle, handle_len);
 
-       return(do_close(fd_in, fd_out, handle, handle_len));
+done:
+       close(local_fd);
+       buffer_free(&msg);
+       xfree(handle);
+       return status;
 }
 
 int
@@ -693,6 +693,7 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
        Buffer msg;
        struct stat sb;
        Attrib a;
+       int status;
 
        if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
                error("Couldn't open local file \"%s\" for reading: %s",
@@ -743,7 +744,6 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
        for(;;) {
                int len;
                char data[COPY_SIZE];
-               u_int status;
 
                /*
                 * Can't use atomicio here because it returns 0 on EOF, thus losing
@@ -774,24 +774,29 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
                        error("Couldn't write to remote file \"%s\": %s",
                            remote_path, fx2txt(status));
                        do_close(fd_in, fd_out, handle, handle_len);
-                       xfree(handle);
                        close(local_fd);
-                       return(-1);
+                       goto done;
                }
                debug3("In write loop, got %d offset %llu", len,
                    (unsigned long long)offset);
 
                offset += len;
        }
-       xfree(handle);
-       buffer_free(&msg);
 
        if (close(local_fd) == -1) {
                error("Couldn't close local file \"%s\": %s", local_path,
                    strerror(errno));
                do_close(fd_in, fd_out, handle, handle_len);
-               return(-1);
+               status = -1;
+               goto done;
        }
 
-       return(do_close(fd_in, fd_out, handle, handle_len));
+       status = do_close(fd_in, fd_out, handle, handle_len);
+
+done:
+       xfree(handle);
+       buffer_free(&msg);
+       return status;
 }
+
+
index aed9b339a609464779e80dee27c293636ee92a30..3310eabab57778792d0a43cc6c012dc7f5a88146 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sftp-common.c,v 1.1 2001/02/04 11:11:54 djm Exp $");
+RCSID("$OpenBSD: sftp-common.c,v 1.2 2001/02/06 23:50:10 markus Exp $");
 
 #include "buffer.h"
 #include "bufaux.h"
@@ -121,13 +121,13 @@ fx2txt(int status)
 {
        switch (status) {
        case SSH2_FX_OK:
-               return("No Error");
+               return("No error");
        case SSH2_FX_EOF:
-               return("End of File");
+               return("End of file");
        case SSH2_FX_NO_SUCH_FILE:
-               return("No Such File");
+               return("No such file or directory");
        case SSH2_FX_PERMISSION_DENIED:
-               return("Permission Denied");
+               return("Permission denied");
        case SSH2_FX_FAILURE:
                return("Failure");
        case SSH2_FX_BAD_MESSAGE:
index 02e0d38c029a8422312cf9d17cb2042d3c0997ba..8b5ae3aefb616492dfd533c92b4fe4438f7723e5 100644 (file)
 
 /* XXX: finish implementation of all commands */
 /* XXX: do fnmatch() instead of using raw pathname */
+/* XXX: globbed ls */
 /* XXX: recursive operations */
 
 #include "includes.h"
-RCSID("$OpenBSD: sftp-int.c,v 1.7 2001/02/05 00:02:32 deraadt Exp $");
+RCSID("$OpenBSD: sftp-int.c,v 1.19 2001/02/09 11:46:24 djm Exp $");
 
 #include "buffer.h"
 #include "xmalloc.h"
@@ -70,28 +71,29 @@ struct CMD {
 };
 
 const struct CMD cmds[] = {
-       { "CD",         I_CHDIR },
-       { "CHDIR",      I_CHDIR },
-       { "CHGRP",      I_CHGRP },
-       { "CHMOD",      I_CHMOD },
-       { "CHOWN",      I_CHOWN },
-       { "EXIT",       I_QUIT },
-       { "GET",        I_GET },
-       { "HELP",       I_HELP },
-       { "LCD",        I_LCHDIR },
-       { "LCHDIR",     I_LCHDIR },
-       { "LLS",        I_LLS },
-       { "LMKDIR",     I_LMKDIR },
-       { "LPWD",       I_LPWD },
-       { "LS",         I_LS },
-       { "LUMASK",     I_LUMASK },
-       { "MKDIR",      I_MKDIR },
-       { "PUT",        I_PUT },
-       { "PWD",        I_PWD },
-       { "QUIT",       I_QUIT },
-       { "RENAME",     I_RENAME },
-       { "RM",         I_RM },
-       { "RMDIR",      I_RMDIR },
+       { "cd",         I_CHDIR },
+       { "chdir",      I_CHDIR },
+       { "chgrp",      I_CHGRP },
+       { "chmod",      I_CHMOD },
+       { "chown",      I_CHOWN },
+       { "dir",        I_LS },
+       { "exit",       I_QUIT },
+       { "get",        I_GET },
+       { "help",       I_HELP },
+       { "lcd",        I_LCHDIR },
+       { "lchdir",     I_LCHDIR },
+       { "lls",        I_LLS },
+       { "lmkdir",     I_LMKDIR },
+       { "lpwd",       I_LPWD },
+       { "ls",         I_LS },
+       { "lumask",     I_LUMASK },
+       { "mkdir",      I_MKDIR },
+       { "put",        I_PUT },
+       { "pwd",        I_PWD },
+       { "quit",       I_QUIT },
+       { "rename",     I_RENAME },
+       { "rm",         I_RM },
+       { "rmdir",      I_RMDIR },
        { "!",          I_SHELL },
        { "?",          I_HELP },
        { NULL,                 -1}
@@ -101,28 +103,29 @@ void
 help(void)
 {
        printf("Available commands:\n");
-       printf("CD path                       Change remote directory to 'path'\n");
-       printf("LCD path                      Change local directory to 'path'\n");
-       printf("CHGRP grp path                Change group of file 'path' to 'grp'\n");
-       printf("CHMOD mode path               Change permissions of file 'path' to 'mode'\n");
-       printf("CHOWN own path                Change owner of file 'path' to 'own'\n");
-       printf("HELP                          Display this help text\n");
-       printf("GET remote-path [local-path]  Download file\n");
-       printf("LLS [ls options] [path]       Display local directory listing\n");
-       printf("LMKDIR path                   Create local directory\n");
-       printf("LPWD                          Print local working directory\n");
-       printf("LS [path]                     Display remote directory listing\n");
-       printf("LUMASK umask                  Set local umask to 'umask'\n");
-       printf("MKDIR path                    Create remote directory\n");
-       printf("PUT local-path [remote-path]  Upload file\n");
-       printf("PWD                           Display remote working directory\n");
-       printf("EXIT                          Quit sftp\n");
-       printf("QUIT                          Quit sftp\n");
-       printf("RENAME oldpath newpath        Rename remote file\n");
-       printf("RMDIR path                    Remove remote directory\n");
-       printf("RM path                       Delete remote file\n");
+       printf("cd path                       Change remote directory to 'path'\n");
+       printf("lcd path                      Change local directory to 'path'\n");
+       printf("chgrp grp path                Change group of file 'path' to 'grp'\n");
+       printf("chmod mode path               Change permissions of file 'path' to 'mode'\n");
+       printf("chown own path                Change owner of file 'path' to 'own'\n");
+       printf("help                          Display this help text\n");
+       printf("get remote-path [local-path]  Download file\n");
+       printf("lls [ls-options [path]]       Display local directory listing\n");
+       printf("lmkdir path                   Create local directory\n");
+       printf("lpwd                          Print local working directory\n");
+       printf("ls [path]                     Display remote directory listing\n");
+       printf("lumask umask                  Set local umask to 'umask'\n");
+       printf("mkdir path                    Create remote directory\n");
+       printf("put local-path [remote-path]  Upload file\n");
+       printf("pwd                           Display remote working directory\n");
+       printf("exit                          Quit sftp\n");
+       printf("quit                          Quit sftp\n");
+       printf("rename oldpath newpath        Rename remote file\n");
+       printf("rmdir path                    Remove remote directory\n");
+       printf("rm path                       Delete remote file\n");
        printf("!command                      Execute 'command' in local shell\n");
        printf("!                             Escape to local shell\n");
+       printf("?                             Synonym for help\n");
 }
 
 void
@@ -166,13 +169,15 @@ void
 local_do_ls(const char *args)
 {
        if (!args || !*args)
-               local_do_shell("ls");
+               local_do_shell(_PATH_LS);
        else {
-               char *buf = xmalloc(8 + strlen(args) + 1);
+               int len = strlen(_PATH_LS " ") + strlen(args) + 1;
+               char *buf = xmalloc(len);
 
                /* XXX: quoting - rip quoting code from ftp? */
-               sprintf(buf, "/bin/ls %s", args);
+               snprintf(buf, len, _PATH_LS " %s", args);
                local_do_shell(buf);
+               xfree(buf);
        }
 }
 
@@ -198,7 +203,7 @@ parse_getput_flags(const char **cpp, int *pflag)
 
        /* Check for flags */
        if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) {
-               switch (*cp) {
+               switch (cp[1]) {
                case 'P':
                        *pflag = 1;
                        break;
@@ -216,50 +221,49 @@ parse_getput_flags(const char **cpp, int *pflag)
 int
 get_pathname(const char **cpp, char **path)
 {
-       const char *quot, *cp = *cpp;
+       const char *cp = *cpp, *end;
+       char quot;
        int i;
 
        cp += strspn(cp, WHITESPACE);
        if (!*cp) {
                *cpp = cp;
                *path = NULL;
-               return(0);
+               return (0);
        }
 
        /* Check for quoted filenames */
        if (*cp == '\"' || *cp == '\'') {
-               quot = cp++;
-               for(i = 0; cp[i] && cp[i] != *quot; i++)
-                       ;
-               if (!cp[i]) {
+               quot = *cp++;
+               
+               end = strchr(cp, quot);
+               if (end == NULL) {
                        error("Unterminated quote");
-                       *path = NULL;
-                       return(-1);
+                       goto fail;
                }
-               if (i == 0) {
+               if (cp == end) {
                        error("Empty quotes");
-                       *path = NULL;
-                       return(-1);
+                       goto fail;
                }
-               *path = xmalloc(i + 1);
-               memcpy(*path, cp, i);
-               (*path)[i] = '\0';
-               cp += i + 1;
-               *cpp = cp + strspn(cp, WHITESPACE);
-               return(0);
+               *cpp = end + 1 + strspn(end + 1, WHITESPACE);
+       } else {
+               /* Read to end of filename */
+               end = strpbrk(cp, WHITESPACE);
+               if (end == NULL)
+                       end = strchr(cp, '\0');
+               *cpp = end + strspn(end, WHITESPACE);
        }
 
-       /* Read to end of filename */
-       for(i = 0; cp[i] && cp[i] != ' '; i++)
-               ;
+       i = end - cp;
 
        *path = xmalloc(i + 1);
        memcpy(*path, cp, i);
        (*path)[i] = '\0';
-       cp += i;
-       *cpp = cp + strspn(cp, WHITESPACE);
-
        return(0);
+
+ fail:
+       *path = NULL;
+       return (-1);
 }
 
 int
@@ -270,7 +274,6 @@ infer_path(const char *p, char **ifp)
        debug("XXX: P = \"%s\"", p);
 
        cp = strrchr(p, '/');
-
        if (cp == NULL) {
                *ifp = xstrdup(p);
                return(0);
@@ -421,14 +424,13 @@ parse_args(const char **cpp, int *pflag, unsigned long *n_arg,
        }
 
        *cpp = cp;
-
        return(cmdnum);
 }
 
 int
 parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
 {
-       char *path1, *path2;
+       char *path1, *path2, *tmp;
        int pflag, cmdnum;
        unsigned long n_arg;
        Attrib a, *aa;
@@ -471,12 +473,44 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
                break;
        case I_CHDIR:
                path1 = make_absolute(path1, *pwd);
+               if ((tmp = do_realpath(in, out, path1)) == NULL)
+                       break;
+               if ((aa = do_stat(in, out, tmp)) == NULL) {
+                       xfree(tmp);
+                       break;
+               }
+               if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
+                       error("Can't change directory: Can't check target");
+                       xfree(tmp);
+                       break;
+               }
+               if (!S_ISDIR(aa->perm)) {
+                       error("Can't change directory: \"%s\" is not "
+                           "a directory", tmp);
+                       xfree(tmp);
+                       break;
+               }
                xfree(*pwd);
-               *pwd = do_realpath(in, out, path1);
+               *pwd = tmp;
                break;
        case I_LS:
+               if (!path1) {
+                       do_ls(in, out, *pwd);
+                       break;
+               }
                path1 = make_absolute(path1, *pwd);
-               do_ls(in, out, path1?path1:*pwd);
+               if ((tmp = do_realpath(in, out, path1)) == NULL)
+                       break;
+               xfree(path1);
+               path1 = tmp;
+               if ((aa = do_stat(in, out, path1)) == NULL)
+                       break;
+               if ((aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && 
+                   !S_ISDIR(aa->perm)) {
+                       error("Can't ls: \"%s\" is not a directory", path1);
+                       break;
+               }
+               do_ls(in, out, path1);
                break;
        case I_LCHDIR:
                if (chdir(path1) == -1)
@@ -485,7 +519,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
                break;
        case I_LMKDIR:
                if (mkdir(path1, 0777) == -1)
-                       error("Couldn't create local directory to "
+                       error("Couldn't create local directory "
                            "\"%s\": %s", path1, strerror(errno));
                break;
        case I_LLS:
@@ -506,23 +540,27 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
                break;
        case I_CHOWN:
                path1 = make_absolute(path1, *pwd);
-               aa = do_stat(in, out, path1);
+               if (!(aa = do_stat(in, out, path1)))
+                       break;
                if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
                        error("Can't get current ownership of "
                            "remote file \"%s\"", path1);
                        break;
                }
+               aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
                aa->uid = n_arg;
                do_setstat(in, out, path1, aa);
                break;
        case I_CHGRP:
                path1 = make_absolute(path1, *pwd);
-               aa = do_stat(in, out, path1);
+               if (!(aa = do_stat(in, out, path1)))
+                       break;
                if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
                        error("Can't get current ownership of "
                            "remote file \"%s\"", path1);
                        break;
                }
+               aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
                aa->gid = n_arg;
                do_setstat(in, out, path1, aa);
                break;
@@ -550,7 +588,6 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
                xfree(path1);
        if (path2)
                xfree(path2);
-
        return(0);
 }
 
@@ -564,8 +601,8 @@ interactive_loop(int fd_in, int fd_out)
        if (pwd == NULL)
                fatal("Need cwd");
 
-       setvbuf(stdout, (char *)NULL, _IOLBF, 0);
-       setvbuf(stdin, (char *)NULL, _IOLBF, 0);
+       setvbuf(stdout, NULL, _IOLBF, 0);
+       setvbuf(stdin, NULL, _IOLBF, 0);
 
        for(;;) {
                char *cp;
diff --git a/sftp.1 b/sftp.1
index 59206b65444d70f6a36ee163ab5f03324178262e..84edc4d67e081121ef596a9ef0da920c7ad91699 100644 (file)
--- a/sftp.1
+++ b/sftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.1 2001/02/04 11:11:54 djm Exp $
+.\" $OpenBSD: sftp.1,v 1.5 2001/02/07 18:10:39 stevesk Exp $
 .\"
 .\" Copyright (c) 2001 Damien Miller. All rights reserved.
 .\"
@@ -30,7 +30,7 @@
 .Nd Secure file tranfer program
 .Sh SYNOPSIS
 .Nm sftp
-.Op Fl v Li | Fl C
+.Op Fl vC
 .Op Fl o Ar ssh_option
 .Op Ar hostname | user@hostname
 .Sh DESCRIPTION
@@ -44,113 +44,122 @@ It may also use many features of ssh, such as public key authentication and
 compression.
 .Nm
 connects and logs into the specified
-.Ar hostname
+.Ar hostname ,
 then enters an interactive command mode.
 .Pp
 The options are as follows:
 .Bl -tag -width Ds
+.It Fl v
+Raise logging level. This option is also passed to ssh.
 .It Fl C
 Enables compression (via ssh's 
 .Fl C
 flag)
-.It Fl v
-Raise logging level. This option is also passed to ssh.
 .It Fl o Ar ssh_option
 Specify an option to be directly passed to
 .Xr ssh 1 .
 .El
 .Sh INTERACTIVE COMMANDS
-Once in interactive mode
-.Nm ,
+Once in interactive mode,
+.Nm
 understands a set of commands similar to those of 
 .Xr ftp 1 .
 Commands are case insensitive.
 .Bl -tag -width Ds
-.It Ic CD Ar path
+.It Ic cd Ar path
 Change remote directory to 
-.Ar path
-.It Ic LCD Ar path
+.Ar path .
+.It Ic lcd Ar path
 Change local directory to 
-.Ar path
-.It Ic CHGRP Ar grp Ar path
+.Ar path .
+.It Ic chgrp Ar grp Ar path
 Change group of file 
-.Ar path to 
+.Ar path
+to
 .Ar grp .
 .Ar grp
-must be numeric.
-.It Ic CHMOD Ar mode Ar path
+must be a numeric GID.
+.It Ic chmod Ar mode Ar path
 Change permissions of file 
-.Ar path to 
-.Ar mode
-.It Ic CHOWN Ar own Ar path
+.Ar path
+to
+.Ar mode .
+.It Ic chown Ar own Ar path
 Change owner of file 
-.Ar path to 
+.Ar path
+to
 .Ar own .
 .Ar own
 must be a numeric UID.
-.It Ic HELP
-Display help text
-.It Ic GET Ar remote-file Op Ar local-file
+.It Ic help
+Display help text.
+.It Ic get Ar remote-path Op Ar local-path
 Retrieve the
-.Ar remote-file
+.Ar remote-path
 and store it on the local machine.
 If the local
-file name is not specified, it is given the same name it has on the 
+path name is not specified, it is given the same name it has on the 
 remote machine.
-.It Ic LLS Op Ar ls-options Op Ar path
+.It Ic lls Op Ar ls-options Op Ar path
 Display local directory listing of either 
 .Ar path
 or current directory if
 .Ar path
-was not specified.
-.It Ic LMKDIR Ar path
+is not specified.
+.It Ic lmkdir Ar path
 Create local directory specified by
-.Ar path
-.It Ic LPWD
-Print local working directory
-.It Ic LS Op Ar path
+.Ar path .
+.It Ic lpwd
+Print local working directory.
+.It Ic ls Op Ar path
 Display remote directory listing of either
 .Ar path
-or current directory, is
-.Ar path not specified.
-.It Ic LUMASK Ar umask
+or current directory if
+.Ar path
+is not specified.
+.It Ic lumask Ar umask
 Set local umask to 
-.Ar umask
-.It Ic MKDIR Ar path
+.Ar umask .
+.It Ic mkdir Ar path
 Create remote directory specified by
-.Ar path
-.It Ic PUT local-file Op Ar remote-file
+.Ar path .
+.It Ic put Ar local-path Op Ar remote-path
 Upload
-.Ar local-file
-and store it on the remote machine. If the local file name is not specified, 
+.Ar local-path
+and store it on the remote machine. If the remote path name is not specified, 
 it is given the same name it has on the local machine.
-.It Ic PWD
-Display remote working directory
-.It Ic EXIT
-Quit sftp
-.It Ic QUIT
-Quit sftp
-.It Ic RENAME Ar oldpath Ar newpath
+.It Ic pwd
+Display remote working directory.
+.It Ic exit
+Quit sftp.
+.It Ic quit
+Quit sftp.
+.It Ic rename Ar oldpath Ar newpath
 Rename remote file from
 .Ar oldpath
 to
-.Ar newpath
-.It Ic RMDIR Ar path
+.Ar newpath .
+.It Ic rmdir Ar path
 Remove remote directory specified by
-.Ar path
-.It Ic RM Ar path
+.Ar path .
+.It Ic rm Ar path
 Delete remote file specified by
-.Ar path
+.Ar path .
 .It Ic ! Ar command
 Execute 
 .Ar command
-in local shell
+in local shell.
 .It Ic !
-Escape to local shell
+Escape to local shell.
+.It Ic ?
+Synonym for help.
+.El
 .Sh AUTHORS
 Damien Miller <djm@mindrot.org>
 .Sh SEE ALSO
 .Xr ssh 1 ,
 .Xr ssh-add 1 ,
 .Xr ssh-keygen 1 ,
-.Xr sshd 8
+.Xr sshd 8 ,
+.Xr scp 1
+
diff --git a/sftp.c b/sftp.c
index 27873d034a54aa14116dde6e748d91166cc4bf91..b4775c02f20e96b80a9e6736009cfed3257ed4d6 100644 (file)
--- a/sftp.c
+++ b/sftp.c
@@ -24,7 +24,7 @@
 
 #include "includes.h"
 
-RCSID("$OpenBSD: sftp.c,v 1.2 2001/02/04 15:32:25 stevesk Exp $");
+RCSID("$OpenBSD: sftp.c,v 1.7 2001/02/08 00:04:52 markus Exp $");
 
 /* XXX: commandline mode */
 /* XXX: copy between two remote hosts (commandline) */
@@ -40,6 +40,10 @@ RCSID("$OpenBSD: sftp.c,v 1.2 2001/02/04 15:32:25 stevesk Exp $");
 #include "sftp-client.h"
 #include "sftp-int.h"
 
+int use_ssh1 = 0;
+char *ssh_program = _PATH_SSH_PROGRAM;
+char *sftp_server = NULL;
+
 void
 connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
 {
@@ -72,8 +76,8 @@ connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
                close(*out);
                close(c_in);
                close(c_out);
-               execv(_PATH_SSH_PROGRAM, args);
-               fprintf(stderr, "exec: %s", strerror(errno));
+               execv(ssh_program, args);
+               fprintf(stderr, "exec: %s: %s\n", ssh_program, strerror(errno));
                exit(1);
        }
 
@@ -87,16 +91,24 @@ make_ssh_args(char *add_arg)
        static char **args = NULL;
        static int nargs = 0;
        char debug_buf[4096];
-       int i;
+       int i, use_subsystem = 1;
+
+       /* no subsystem if protocol 1 or the server-spec contains a '/' */
+       if (use_ssh1 ||
+           (sftp_server != NULL && strchr(sftp_server, '/') != NULL))
+               use_subsystem = 0;
 
        /* Init args array */
        if (args == NULL) {
-               nargs = 4;
+               nargs = use_subsystem ? 6 : 5;
                i = 0;
                args = xmalloc(sizeof(*args) * nargs);
                args[i++] = "ssh";
-               args[i++] = "-oProtocol=2";
-               args[i++] = "-s";
+               args[i++] = use_ssh1 ? "-oProtocol=1" : "-oProtocol=2";
+               if (use_subsystem)
+                       args[i++] = "-s";
+               args[i++] = "-oForwardAgent=no";
+               args[i++] = "-oForwardX11=no";
                args[i++] = NULL;
        }
 
@@ -110,7 +122,10 @@ make_ssh_args(char *add_arg)
        }
 
        /* Otherwise finish up and return the arg array */
-       make_ssh_args("sftp");
+       if (sftp_server != NULL)
+               make_ssh_args(sftp_server);
+       else
+               make_ssh_args("sftp");
 
        /* XXX: overflow - doesn't grow debug_buf */
        debug_buf[0] = '\0';
@@ -128,49 +143,70 @@ make_ssh_args(char *add_arg)
 void
 usage(void)
 {
-       fprintf(stderr, "usage: sftp [-vC] [-osshopt=value] [user@]host\n");
+       fprintf(stderr, "usage: sftp [-1vC] [-osshopt=value] [user@]host\n");
        exit(1);
 }
 
 int
 main(int argc, char **argv)
 {
-       int in, out, i, debug_level, compress_flag;
+       int in, out, ch, debug_level, compress_flag;
        pid_t sshpid;
-       char *cp;
+       char *host, *userhost;
        LogLevel ll;
+       extern int optind;
+       extern char *optarg;
 
        debug_level = compress_flag = 0;
-       for(i = 1; i < argc && argv[i][0] == '-'; i++) {
-               if (!strcmp(argv[i], "-v"))
-                       debug_level = MIN(3, debug_level + 1);
-               else if (!strcmp(argv[i], "-C"))
+
+       while ((ch = getopt(argc, argv, "1hvCo:s:S:")) != -1) {
+               switch (ch) {
+               case 'C':
                        compress_flag = 1;
-               else if (!strncmp(argv[i], "-o", 2)) {
-                       make_ssh_args(argv[i]);
-               } else {
-                       fprintf(stderr, "Unknown option \"%s\"\n", argv[i]);
+                       break;
+               case 'v':
+                       debug_level = MIN(3, debug_level + 1);
+                       break;
+               case 'o':
+                       make_ssh_args("-o");
+                       make_ssh_args(optarg);
+                       break;
+               case '1':
+                       use_ssh1 = 1;
+                       if (sftp_server == NULL)
+                               sftp_server = _PATH_SFTP_SERVER;
+                       break;
+               case 's':
+                       sftp_server = optarg;
+                       break;
+               case 'S':
+                       ssh_program = optarg;
+                       break;
+               case 'h':
+               default:
                        usage();
                }
        }
 
-       if (i == argc || argc > (i + 1))
+       if (optind == argc || argc > (optind + 1))
                usage();
 
-       if ((cp = strchr(argv[i], '@')) == NULL)
-               cp = argv[i];
+       userhost = argv[optind];
+
+       if ((host = strchr(userhost, '@')) == NULL)
+               host = userhost;
        else {
-               *cp = '\0';
-               if (!argv[i][0]) {
+               *host = '\0';
+               if (!userhost[0]) {
                        fprintf(stderr, "Missing username\n");
                        usage();
                }
                make_ssh_args("-l");
-               make_ssh_args(argv[i]);
-               cp++;
+               make_ssh_args(userhost);
+               host++;
        }
 
-       if (!*cp) {
+       if (!*host) {
                fprintf(stderr, "Missing hostname\n");
                usage();
        }
@@ -200,9 +236,9 @@ main(int argc, char **argv)
 
        log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
 
-       make_ssh_args(cp);
+       make_ssh_args(host);
 
-       fprintf(stderr, "Connecting to %s...\n", cp);
+       fprintf(stderr, "Connecting to %s...\n", host);
 
        connect_to_server(make_ssh_args(NULL), &in, &out, &sshpid);
 
@@ -216,7 +252,8 @@ main(int argc, char **argv)
        if (kill(sshpid, SIGHUP) == -1)
                fatal("Couldn't terminate ssh process: %s", strerror(errno));
 
-       /* XXX: wait? */
+       if (waitpid(sshpid, NULL, 0) == -1)
+               fatal("Couldn't wait for ssh process: %s", strerror(errno));
 
        exit(0);
 }
This page took 0.104044 seconds and 5 git commands to generate.