]> 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>
 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
 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@
 
 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@
 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
        $(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
        $(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 -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
        -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>
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
 #define _PATH_CP                       "cp"
 #endif
 
 #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
 /* 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"
 /* 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"
 
 #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);
                            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;
                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;
        char *handle;
        Buffer msg;
        Attrib junk, *a;
+       int status;
 
        a = do_stat(fd_in, fd_out, remote_path);
        if (a == NULL)
 
        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) {
                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;
 
                        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);
                                    "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",
                        }
                } 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);
 
                        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);
                    (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);
                        xfree(data);
-                       buffer_free(&msg);
-                       return(-1);
+                       goto done;
                }
 
                offset += len;
                xfree(data);
        }
                }
 
                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
 }
 
 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;
        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",
 
        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];
        for(;;) {
                int len;
                char data[COPY_SIZE];
-               u_int status;
 
                /*
                 * Can't use atomicio here because it returns 0 on EOF, thus losing
 
                /*
                 * 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);
                        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);
                        close(local_fd);
-                       return(-1);
+                       goto done;
                }
                debug3("In write loop, got %d offset %llu", len,
                    (unsigned long long)offset);
 
                offset += len;
        }
                }
                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);
 
        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"
  */
 
 #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"
 
 #include "buffer.h"
 #include "bufaux.h"
@@ -121,13 +121,13 @@ fx2txt(int status)
 {
        switch (status) {
        case SSH2_FX_OK:
 {
        switch (status) {
        case SSH2_FX_OK:
-               return("No Error");
+               return("No error");
        case SSH2_FX_EOF:
        case SSH2_FX_EOF:
-               return("End of File");
+               return("End of file");
        case SSH2_FX_NO_SUCH_FILE:
        case SSH2_FX_NO_SUCH_FILE:
-               return("No Such File");
+               return("No such file or directory");
        case SSH2_FX_PERMISSION_DENIED:
        case SSH2_FX_PERMISSION_DENIED:
-               return("Permission Denied");
+               return("Permission denied");
        case SSH2_FX_FAILURE:
                return("Failure");
        case SSH2_FX_BAD_MESSAGE:
        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: finish implementation of all commands */
 /* XXX: do fnmatch() instead of using raw pathname */
+/* XXX: globbed ls */
 /* XXX: recursive operations */
 
 #include "includes.h"
 /* 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"
 
 #include "buffer.h"
 #include "xmalloc.h"
@@ -70,28 +71,29 @@ struct CMD {
 };
 
 const struct CMD cmds[] = {
 };
 
 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}
        { "!",          I_SHELL },
        { "?",          I_HELP },
        { NULL,                 -1}
@@ -101,28 +103,29 @@ void
 help(void)
 {
        printf("Available commands:\n");
 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("!command                      Execute 'command' in local shell\n");
        printf("!                             Escape to local shell\n");
+       printf("?                             Synonym for help\n");
 }
 
 void
 }
 
 void
@@ -166,13 +169,15 @@ void
 local_do_ls(const char *args)
 {
        if (!args || !*args)
 local_do_ls(const char *args)
 {
        if (!args || !*args)
-               local_do_shell("ls");
+               local_do_shell(_PATH_LS);
        else {
        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? */
 
                /* XXX: quoting - rip quoting code from ftp? */
-               sprintf(buf, "/bin/ls %s", args);
+               snprintf(buf, len, _PATH_LS " %s", args);
                local_do_shell(buf);
                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])) {
 
        /* Check for flags */
        if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) {
-               switch (*cp) {
+               switch (cp[1]) {
                case 'P':
                        *pflag = 1;
                        break;
                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)
 {
 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;
        int i;
 
        cp += strspn(cp, WHITESPACE);
        if (!*cp) {
                *cpp = cp;
                *path = NULL;
-               return(0);
+               return (0);
        }
 
        /* Check for quoted filenames */
        if (*cp == '\"' || *cp == '\'') {
        }
 
        /* 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");
                        error("Unterminated quote");
-                       *path = NULL;
-                       return(-1);
+                       goto fail;
                }
                }
-               if (i == 0) {
+               if (cp == end) {
                        error("Empty quotes");
                        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';
 
        *path = xmalloc(i + 1);
        memcpy(*path, cp, i);
        (*path)[i] = '\0';
-       cp += i;
-       *cpp = cp + strspn(cp, WHITESPACE);
-
        return(0);
        return(0);
+
+ fail:
+       *path = NULL;
+       return (-1);
 }
 
 int
 }
 
 int
@@ -270,7 +274,6 @@ infer_path(const char *p, char **ifp)
        debug("XXX: P = \"%s\"", p);
 
        cp = strrchr(p, '/');
        debug("XXX: P = \"%s\"", p);
 
        cp = strrchr(p, '/');
-
        if (cp == NULL) {
                *ifp = xstrdup(p);
                return(0);
        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;
        }
 
        *cpp = cp;
-
        return(cmdnum);
 }
 
 int
 parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
 {
        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;
        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);
                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);
                xfree(*pwd);
-               *pwd = do_realpath(in, out, path1);
+               *pwd = tmp;
                break;
        case I_LS:
                break;
        case I_LS:
+               if (!path1) {
+                       do_ls(in, out, *pwd);
+                       break;
+               }
                path1 = make_absolute(path1, *pwd);
                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)
                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)
                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:
                            "\"%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);
                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;
                }
                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->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;
                }
                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;
                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);
                xfree(path1);
        if (path2)
                xfree(path2);
-
        return(0);
 }
 
        return(0);
 }
 
@@ -564,8 +601,8 @@ interactive_loop(int fd_in, int fd_out)
        if (pwd == NULL)
                fatal("Need cwd");
 
        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;
 
        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.
 .\"
 .\"
 .\" Copyright (c) 2001 Damien Miller. All rights reserved.
 .\"
@@ -30,7 +30,7 @@
 .Nd Secure file tranfer program
 .Sh SYNOPSIS
 .Nm sftp
 .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
 .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
 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
 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 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
 .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
 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 
 Change remote directory to 
-.Ar path
-.It Ic LCD Ar path
+.Ar path .
+.It Ic lcd Ar path
 Change local directory to 
 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 
 Change group of file 
-.Ar path to 
+.Ar path
+to
 .Ar grp .
 .Ar grp
 .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 
 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 
 Change owner of file 
-.Ar path to 
+.Ar path
+to
 .Ar own .
 .Ar own
 must be a numeric UID.
 .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
 Retrieve the
-.Ar remote-file
+.Ar remote-path
 and store it on the local machine.
 If the local
 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.
 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
 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
 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
 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 
 Set local umask to 
-.Ar umask
-.It Ic MKDIR Ar path
+.Ar umask .
+.It Ic mkdir Ar path
 Create remote directory specified by
 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
 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 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
 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
 Remove remote directory specified by
-.Ar path
-.It Ic RM Ar path
+.Ar path .
+.It Ic rm Ar path
 Delete remote file specified by
 Delete remote file specified by
-.Ar path
+.Ar path .
 .It Ic ! Ar command
 Execute 
 .Ar command
 .It Ic ! Ar command
 Execute 
 .Ar command
-in local shell
+in local shell.
 .It Ic !
 .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 ,
 .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"
 
 
 #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) */
 
 /* 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"
 
 #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)
 {
 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);
                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);
        }
 
                exit(1);
        }
 
@@ -87,16 +91,24 @@ make_ssh_args(char *add_arg)
        static char **args = NULL;
        static int nargs = 0;
        char debug_buf[4096];
        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) {
 
        /* Init args array */
        if (args == NULL) {
-               nargs = 4;
+               nargs = use_subsystem ? 6 : 5;
                i = 0;
                args = xmalloc(sizeof(*args) * nargs);
                args[i++] = "ssh";
                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;
        }
 
                args[i++] = NULL;
        }
 
@@ -110,7 +122,10 @@ make_ssh_args(char *add_arg)
        }
 
        /* Otherwise finish up and return the arg array */
        }
 
        /* 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';
 
        /* XXX: overflow - doesn't grow debug_buf */
        debug_buf[0] = '\0';
@@ -128,49 +143,70 @@ make_ssh_args(char *add_arg)
 void
 usage(void)
 {
 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)
 {
        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;
        pid_t sshpid;
-       char *cp;
+       char *host, *userhost;
        LogLevel ll;
        LogLevel ll;
+       extern int optind;
+       extern char *optarg;
 
        debug_level = compress_flag = 0;
 
        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;
                        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();
                }
        }
 
                        usage();
                }
        }
 
-       if (i == argc || argc > (i + 1))
+       if (optind == argc || argc > (optind + 1))
                usage();
 
                usage();
 
-       if ((cp = strchr(argv[i], '@')) == NULL)
-               cp = argv[i];
+       userhost = argv[optind];
+
+       if ((host = strchr(userhost, '@')) == NULL)
+               host = userhost;
        else {
        else {
-               *cp = '\0';
-               if (!argv[i][0]) {
+               *host = '\0';
+               if (!userhost[0]) {
                        fprintf(stderr, "Missing username\n");
                        usage();
                }
                make_ssh_args("-l");
                        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();
        }
                fprintf(stderr, "Missing hostname\n");
                usage();
        }
@@ -200,9 +236,9 @@ main(int argc, char **argv)
 
        log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
 
 
        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);
 
 
        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));
 
        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);
 }
 
        exit(0);
 }
This page took 0.104138 seconds and 5 git commands to generate.