- (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
This commit is contained in:
parent
4192c46791
commit
d7686fd1fb
66
ChangeLog
66
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
|
20010209
|
||||||
- (bal) patch to vis.c to deal with HAVE_VIS right by Robert Mooney
|
- (bal) patch to vis.c to deal with HAVE_VIS right by Robert Mooney
|
||||||
<rjmooney@mediaone.net>
|
<rjmooney@mediaone.net>
|
||||||
|
@ -3703,4 +3767,4 @@
|
||||||
- Wrote replacements for strlcpy and mkdtemp
|
- Wrote replacements for strlcpy and mkdtemp
|
||||||
- Released 1.0pre1
|
- Released 1.0pre1
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.709 2001/02/09 11:55:16 djm Exp $
|
$Id: ChangeLog,v 1.710 2001/02/09 13:40:03 djm Exp $
|
||||||
|
|
13
Makefile.in
13
Makefile.in
|
@ -1,4 +1,4 @@
|
||||||
# $Id: Makefile.in,v 1.149 2001/02/07 23:07:09 djm Exp $
|
# $Id: Makefile.in,v 1.150 2001/02/09 13:40:03 djm Exp $
|
||||||
|
|
||||||
prefix=@prefix@
|
prefix=@prefix@
|
||||||
exec_prefix=@exec_prefix@
|
exec_prefix=@exec_prefix@
|
||||||
|
@ -16,10 +16,15 @@ DESTDIR=
|
||||||
VPATH=@srcdir@
|
VPATH=@srcdir@
|
||||||
SSH_PROGRAM=@bindir@/ssh
|
SSH_PROGRAM=@bindir@/ssh
|
||||||
ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
|
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@
|
CC=@CC@
|
||||||
LD=@LD@
|
LD=@LD@
|
||||||
PATHS=-DETCDIR=\"$(sysconfdir)\" -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" -D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\"
|
|
||||||
CFLAGS=@CFLAGS@
|
CFLAGS=@CFLAGS@
|
||||||
CPPFLAGS=@CPPFLAGS@ -I. -I$(srcdir)/openbsd-compat -I$(srcdir) $(PATHS) @DEFS@
|
CPPFLAGS=@CPPFLAGS@ -I. -I$(srcdir)/openbsd-compat -I$(srcdir) $(PATHS) @DEFS@
|
||||||
LIBS=@LIBS@
|
LIBS=@LIBS@
|
||||||
|
@ -162,7 +167,7 @@ install-files:
|
||||||
$(INSTALL) -m 0775 -s ssh-keyscan $(DESTDIR)$(bindir)/ssh-keyscan
|
$(INSTALL) -m 0775 -s ssh-keyscan $(DESTDIR)$(bindir)/ssh-keyscan
|
||||||
$(INSTALL) -m 0755 -s sshd $(DESTDIR)$(sbindir)/sshd
|
$(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 $(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 ssh.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
|
||||||
$(INSTALL) -m 644 scp.[01].out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.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-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)/ssh-keyscan$(EXEEXT)
|
||||||
-rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
|
-rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
|
||||||
-rm -f $(DESTDIR)$(sbindir)/sshd$(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/ssh.1
|
||||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.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-add.1
|
||||||
|
|
|
@ -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>
|
||||||
|
@ -116,6 +116,12 @@
|
||||||
#define _PATH_CP "cp"
|
#define _PATH_CP "cp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* for sftp */
|
||||||
|
#ifndef _PATH_SFTP_SERVER
|
||||||
|
#define _PATH_SFTP_SERVER "/usr/libexec/sftp-server"
|
||||||
|
#endif
|
||||||
|
#define _PATH_LS "ls"
|
||||||
|
|
||||||
/* path to login program */
|
/* path to login program */
|
||||||
#ifndef LOGIN_PROGRAM
|
#ifndef LOGIN_PROGRAM
|
||||||
# ifdef LOGIN_PROGRAM_FALLBACK
|
# ifdef LOGIN_PROGRAM_FALLBACK
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
/* XXX: copy between two remote sites */
|
/* XXX: copy between two remote sites */
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "ssh.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
@ -338,7 +338,9 @@ do_ls(int fd_in, int fd_out, char *path)
|
||||||
SSH2_FXP_NAME, type);
|
SSH2_FXP_NAME, type);
|
||||||
|
|
||||||
count = buffer_get_int(&msg);
|
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++) {
|
for(i = 0; i < count; i++) {
|
||||||
char *filename, *longname;
|
char *filename, *longname;
|
||||||
Attrib *a;
|
Attrib *a;
|
||||||
|
@ -556,6 +558,7 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
|
||||||
char *handle;
|
char *handle;
|
||||||
Buffer msg;
|
Buffer msg;
|
||||||
Attrib junk, *a;
|
Attrib junk, *a;
|
||||||
|
int status;
|
||||||
|
|
||||||
a = do_stat(fd_in, fd_out, remote_path);
|
a = do_stat(fd_in, fd_out, remote_path);
|
||||||
if (a == NULL)
|
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)
|
if (id != expected_id)
|
||||||
fatal("ID mismatch (%d != %d)", id, expected_id);
|
fatal("ID mismatch (%d != %d)", id, expected_id);
|
||||||
if (type == SSH2_FXP_STATUS) {
|
if (type == SSH2_FXP_STATUS) {
|
||||||
int status = buffer_get_int(&msg);
|
status = buffer_get_int(&msg);
|
||||||
|
|
||||||
if (status == SSH2_FX_EOF)
|
if (status == SSH2_FX_EOF)
|
||||||
break;
|
break;
|
||||||
|
@ -644,10 +647,7 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
|
||||||
"file \"%s\" : %s", remote_path,
|
"file \"%s\" : %s", remote_path,
|
||||||
fx2txt(status));
|
fx2txt(status));
|
||||||
do_close(fd_in, fd_out, handle, handle_len);
|
do_close(fd_in, fd_out, handle, handle_len);
|
||||||
xfree(handle);
|
goto done;
|
||||||
close(local_fd);
|
|
||||||
buffer_free(&msg);
|
|
||||||
return(status);
|
|
||||||
}
|
}
|
||||||
} else if (type != SSH2_FXP_DATA) {
|
} else if (type != SSH2_FXP_DATA) {
|
||||||
fatal("Expected SSH2_FXP_DATA(%d) packet, got %d",
|
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",
|
fatal("Received more data than asked for %d > %d",
|
||||||
len, COPY_SIZE);
|
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);
|
(unsigned long long)offset);
|
||||||
if (atomicio(write, local_fd, data, len) != len) {
|
if (atomicio(write, local_fd, data, len) != len) {
|
||||||
error("Couldn't write to \"%s\": %s", local_path,
|
error("Couldn't write to \"%s\": %s", local_path,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
do_close(fd_in, fd_out, handle, handle_len);
|
do_close(fd_in, fd_out, handle, handle_len);
|
||||||
xfree(handle);
|
status = -1;
|
||||||
close(local_fd);
|
|
||||||
xfree(data);
|
xfree(data);
|
||||||
buffer_free(&msg);
|
goto done;
|
||||||
return(-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += len;
|
offset += len;
|
||||||
xfree(data);
|
xfree(data);
|
||||||
}
|
}
|
||||||
xfree(handle);
|
status = do_close(fd_in, fd_out, handle, handle_len);
|
||||||
buffer_free(&msg);
|
|
||||||
close(local_fd);
|
|
||||||
|
|
||||||
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;
|
Buffer msg;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
Attrib a;
|
Attrib a;
|
||||||
|
int status;
|
||||||
|
|
||||||
if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
|
if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
|
||||||
error("Couldn't open local file \"%s\" for reading: %s",
|
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(;;) {
|
for(;;) {
|
||||||
int len;
|
int len;
|
||||||
char data[COPY_SIZE];
|
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",
|
error("Couldn't write to remote file \"%s\": %s",
|
||||||
remote_path, fx2txt(status));
|
remote_path, fx2txt(status));
|
||||||
do_close(fd_in, fd_out, handle, handle_len);
|
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,
|
debug3("In write loop, got %d offset %llu", len,
|
||||||
(unsigned long long)offset);
|
(unsigned long long)offset);
|
||||||
|
|
||||||
offset += len;
|
offset += len;
|
||||||
}
|
}
|
||||||
xfree(handle);
|
|
||||||
buffer_free(&msg);
|
|
||||||
|
|
||||||
if (close(local_fd) == -1) {
|
if (close(local_fd) == -1) {
|
||||||
error("Couldn't close local file \"%s\": %s", local_path,
|
error("Couldn't close local file \"%s\": %s", local_path,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
do_close(fd_in, fd_out, handle, handle_len);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 "buffer.h"
|
||||||
#include "bufaux.h"
|
#include "bufaux.h"
|
||||||
|
@ -121,13 +121,13 @@ fx2txt(int status)
|
||||||
{
|
{
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case SSH2_FX_OK:
|
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:
|
case SSH2_FX_FAILURE:
|
||||||
return("Failure");
|
return("Failure");
|
||||||
case SSH2_FX_BAD_MESSAGE:
|
case SSH2_FX_BAD_MESSAGE:
|
||||||
|
|
199
sftp-int.c
199
sftp-int.c
|
@ -24,10 +24,11 @@
|
||||||
|
|
||||||
/* XXX: finish implementation of all commands */
|
/* XXX: finish implementation of all commands */
|
||||||
/* XXX: do fnmatch() instead of using raw pathname */
|
/* XXX: do fnmatch() instead of using raw pathname */
|
||||||
|
/* XXX: globbed ls */
|
||||||
/* XXX: recursive operations */
|
/* XXX: recursive operations */
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "buffer.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
@ -70,28 +71,29 @@ struct CMD {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct CMD cmds[] = {
|
const struct CMD cmds[] = {
|
||||||
{ "CD", I_CHDIR },
|
{ "cd", I_CHDIR },
|
||||||
{ "CHDIR", I_CHDIR },
|
{ "chdir", I_CHDIR },
|
||||||
{ "CHGRP", I_CHGRP },
|
{ "chgrp", I_CHGRP },
|
||||||
{ "CHMOD", I_CHMOD },
|
{ "chmod", I_CHMOD },
|
||||||
{ "CHOWN", I_CHOWN },
|
{ "chown", I_CHOWN },
|
||||||
{ "EXIT", I_QUIT },
|
{ "dir", I_LS },
|
||||||
{ "GET", I_GET },
|
{ "exit", I_QUIT },
|
||||||
{ "HELP", I_HELP },
|
{ "get", I_GET },
|
||||||
{ "LCD", I_LCHDIR },
|
{ "help", I_HELP },
|
||||||
{ "LCHDIR", I_LCHDIR },
|
{ "lcd", I_LCHDIR },
|
||||||
{ "LLS", I_LLS },
|
{ "lchdir", I_LCHDIR },
|
||||||
{ "LMKDIR", I_LMKDIR },
|
{ "lls", I_LLS },
|
||||||
{ "LPWD", I_LPWD },
|
{ "lmkdir", I_LMKDIR },
|
||||||
{ "LS", I_LS },
|
{ "lpwd", I_LPWD },
|
||||||
{ "LUMASK", I_LUMASK },
|
{ "ls", I_LS },
|
||||||
{ "MKDIR", I_MKDIR },
|
{ "lumask", I_LUMASK },
|
||||||
{ "PUT", I_PUT },
|
{ "mkdir", I_MKDIR },
|
||||||
{ "PWD", I_PWD },
|
{ "put", I_PUT },
|
||||||
{ "QUIT", I_QUIT },
|
{ "pwd", I_PWD },
|
||||||
{ "RENAME", I_RENAME },
|
{ "quit", I_QUIT },
|
||||||
{ "RM", I_RM },
|
{ "rename", I_RENAME },
|
||||||
{ "RMDIR", I_RMDIR },
|
{ "rm", I_RM },
|
||||||
|
{ "rmdir", I_RMDIR },
|
||||||
{ "!", I_SHELL },
|
{ "!", I_SHELL },
|
||||||
{ "?", I_HELP },
|
{ "?", I_HELP },
|
||||||
{ NULL, -1}
|
{ NULL, -1}
|
||||||
|
@ -101,28 +103,29 @@ void
|
||||||
help(void)
|
help(void)
|
||||||
{
|
{
|
||||||
printf("Available commands:\n");
|
printf("Available commands:\n");
|
||||||
printf("CD path Change remote directory to 'path'\n");
|
printf("cd path Change remote directory to 'path'\n");
|
||||||
printf("LCD path Change local 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("chgrp grp path Change group of file 'path' to 'grp'\n");
|
||||||
printf("CHMOD mode path Change permissions of file 'path' to 'mode'\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("chown own path Change owner of file 'path' to 'own'\n");
|
||||||
printf("HELP Display this help text\n");
|
printf("help Display this help text\n");
|
||||||
printf("GET remote-path [local-path] Download file\n");
|
printf("get remote-path [local-path] Download file\n");
|
||||||
printf("LLS [ls options] [path] Display local directory listing\n");
|
printf("lls [ls-options [path]] Display local directory listing\n");
|
||||||
printf("LMKDIR path Create local directory\n");
|
printf("lmkdir path Create local directory\n");
|
||||||
printf("LPWD Print local working directory\n");
|
printf("lpwd Print local working directory\n");
|
||||||
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("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");
|
||||||
printf("QUIT Quit sftp\n");
|
printf("quit Quit sftp\n");
|
||||||
printf("RENAME oldpath newpath Rename remote file\n");
|
printf("rename oldpath newpath Rename remote file\n");
|
||||||
printf("RMDIR path Remove remote directory\n");
|
printf("rmdir path Remove remote directory\n");
|
||||||
printf("RM path Delete remote file\n");
|
printf("rm path Delete remote file\n");
|
||||||
printf("!command Execute 'command' in local shell\n");
|
printf("!command Execute 'command' in local shell\n");
|
||||||
printf("! Escape to 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)
|
local_do_ls(const char *args)
|
||||||
{
|
{
|
||||||
if (!args || !*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 */
|
/* Check for flags */
|
||||||
if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) {
|
if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) {
|
||||||
switch (*cp) {
|
switch (cp[1]) {
|
||||||
case 'P':
|
case 'P':
|
||||||
*pflag = 1;
|
*pflag = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -216,50 +221,49 @@ parse_getput_flags(const char **cpp, int *pflag)
|
||||||
int
|
int
|
||||||
get_pathname(const char **cpp, char **path)
|
get_pathname(const char **cpp, char **path)
|
||||||
{
|
{
|
||||||
const char *quot, *cp = *cpp;
|
const char *cp = *cpp, *end;
|
||||||
|
char quot;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cp += strspn(cp, WHITESPACE);
|
cp += strspn(cp, WHITESPACE);
|
||||||
if (!*cp) {
|
if (!*cp) {
|
||||||
*cpp = cp;
|
*cpp = cp;
|
||||||
*path = NULL;
|
*path = NULL;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for quoted filenames */
|
/* Check for quoted filenames */
|
||||||
if (*cp == '\"' || *cp == '\'') {
|
if (*cp == '\"' || *cp == '\'') {
|
||||||
quot = cp++;
|
quot = *cp++;
|
||||||
for(i = 0; cp[i] && cp[i] != *quot; i++)
|
|
||||||
;
|
end = strchr(cp, quot);
|
||||||
if (!cp[i]) {
|
if (end == NULL) {
|
||||||
error("Unterminated quote");
|
error("Unterminated quote");
|
||||||
*path = NULL;
|
goto fail;
|
||||||
return(-1);
|
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (cp == end) {
|
||||||
error("Empty quotes");
|
error("Empty quotes");
|
||||||
*path = NULL;
|
goto fail;
|
||||||
return(-1);
|
|
||||||
}
|
}
|
||||||
*path = xmalloc(i + 1);
|
*cpp = end + 1 + strspn(end + 1, WHITESPACE);
|
||||||
memcpy(*path, cp, i);
|
} else {
|
||||||
(*path)[i] = '\0';
|
/* Read to end of filename */
|
||||||
cp += i + 1;
|
end = strpbrk(cp, WHITESPACE);
|
||||||
*cpp = cp + strspn(cp, WHITESPACE);
|
if (end == NULL)
|
||||||
return(0);
|
end = strchr(cp, '\0');
|
||||||
|
*cpp = end + strspn(end, WHITESPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read to end of filename */
|
i = end - cp;
|
||||||
for(i = 0; cp[i] && cp[i] != ' '; i++)
|
|
||||||
;
|
|
||||||
|
|
||||||
*path = xmalloc(i + 1);
|
*path = xmalloc(i + 1);
|
||||||
memcpy(*path, cp, i);
|
memcpy(*path, cp, i);
|
||||||
(*path)[i] = '\0';
|
(*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);
|
debug("XXX: P = \"%s\"", p);
|
||||||
|
|
||||||
cp = strrchr(p, '/');
|
cp = strrchr(p, '/');
|
||||||
|
|
||||||
if (cp == NULL) {
|
if (cp == NULL) {
|
||||||
*ifp = xstrdup(p);
|
*ifp = xstrdup(p);
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -421,14 +424,13 @@ parse_args(const char **cpp, int *pflag, unsigned long *n_arg,
|
||||||
}
|
}
|
||||||
|
|
||||||
*cpp = cp;
|
*cpp = cp;
|
||||||
|
|
||||||
return(cmdnum);
|
return(cmdnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
||||||
{
|
{
|
||||||
char *path1, *path2;
|
char *path1, *path2, *tmp;
|
||||||
int pflag, cmdnum;
|
int pflag, cmdnum;
|
||||||
unsigned long n_arg;
|
unsigned long n_arg;
|
||||||
Attrib a, *aa;
|
Attrib a, *aa;
|
||||||
|
@ -471,12 +473,44 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
||||||
break;
|
break;
|
||||||
case I_CHDIR:
|
case I_CHDIR:
|
||||||
path1 = make_absolute(path1, *pwd);
|
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;
|
break;
|
||||||
case I_LS:
|
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;
|
break;
|
||||||
case I_LCHDIR:
|
case I_LCHDIR:
|
||||||
if (chdir(path1) == -1)
|
if (chdir(path1) == -1)
|
||||||
|
@ -485,7 +519,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
||||||
break;
|
break;
|
||||||
case I_LMKDIR:
|
case I_LMKDIR:
|
||||||
if (mkdir(path1, 0777) == -1)
|
if (mkdir(path1, 0777) == -1)
|
||||||
error("Couldn't create local directory to "
|
error("Couldn't create local directory "
|
||||||
"\"%s\": %s", path1, strerror(errno));
|
"\"%s\": %s", path1, strerror(errno));
|
||||||
break;
|
break;
|
||||||
case I_LLS:
|
case I_LLS:
|
||||||
|
@ -506,23 +540,27 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
||||||
break;
|
break;
|
||||||
case I_CHOWN:
|
case I_CHOWN:
|
||||||
path1 = make_absolute(path1, *pwd);
|
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)) {
|
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
|
||||||
error("Can't get current ownership of "
|
error("Can't get current ownership of "
|
||||||
"remote file \"%s\"", path1);
|
"remote file \"%s\"", path1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
|
||||||
aa->uid = n_arg;
|
aa->uid = n_arg;
|
||||||
do_setstat(in, out, path1, aa);
|
do_setstat(in, out, path1, aa);
|
||||||
break;
|
break;
|
||||||
case I_CHGRP:
|
case I_CHGRP:
|
||||||
path1 = make_absolute(path1, *pwd);
|
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)) {
|
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
|
||||||
error("Can't get current ownership of "
|
error("Can't get current ownership of "
|
||||||
"remote file \"%s\"", path1);
|
"remote file \"%s\"", path1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
|
||||||
aa->gid = n_arg;
|
aa->gid = n_arg;
|
||||||
do_setstat(in, out, path1, aa);
|
do_setstat(in, out, path1, aa);
|
||||||
break;
|
break;
|
||||||
|
@ -550,7 +588,6 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
||||||
xfree(path1);
|
xfree(path1);
|
||||||
if (path2)
|
if (path2)
|
||||||
xfree(path2);
|
xfree(path2);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,8 +601,8 @@ interactive_loop(int fd_in, int fd_out)
|
||||||
if (pwd == NULL)
|
if (pwd == NULL)
|
||||||
fatal("Need cwd");
|
fatal("Need cwd");
|
||||||
|
|
||||||
setvbuf(stdout, (char *)NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
setvbuf(stdin, (char *)NULL, _IOLBF, 0);
|
setvbuf(stdin, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
char *cp;
|
char *cp;
|
||||||
|
|
121
sftp.1
121
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
|
.Nd Secure file tranfer program
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm sftp
|
.Nm sftp
|
||||||
.Op Fl v Li | Fl C
|
.Op Fl vC
|
||||||
.Op Fl o Ar ssh_option
|
.Op Fl o Ar ssh_option
|
||||||
.Op Ar hostname | user@hostname
|
.Op Ar hostname | user@hostname
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
|
@ -44,113 +44,122 @@ It may also use many features of ssh, such as public key authentication and
|
||||||
compression.
|
compression.
|
||||||
.Nm
|
.Nm
|
||||||
connects and logs into the specified
|
connects and logs into the specified
|
||||||
.Ar hostname
|
.Ar hostname ,
|
||||||
then enters an interactive command mode.
|
then enters an interactive command mode.
|
||||||
.Pp
|
.Pp
|
||||||
The options are as follows:
|
The options are as follows:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
|
.It Fl v
|
||||||
|
Raise logging level. This option is also passed to ssh.
|
||||||
.It Fl C
|
.It Fl C
|
||||||
Enables compression (via ssh's
|
Enables compression (via ssh's
|
||||||
.Fl C
|
.Fl C
|
||||||
flag)
|
flag)
|
||||||
.It Fl v
|
|
||||||
Raise logging level. This option is also passed to ssh.
|
|
||||||
.It Fl o Ar ssh_option
|
.It Fl o Ar ssh_option
|
||||||
Specify an option to be directly passed to
|
Specify an option to be directly passed to
|
||||||
.Xr ssh 1 .
|
.Xr ssh 1 .
|
||||||
.El
|
.El
|
||||||
.Sh INTERACTIVE COMMANDS
|
.Sh INTERACTIVE COMMANDS
|
||||||
Once in interactive mode
|
Once in interactive mode,
|
||||||
.Nm ,
|
.Nm
|
||||||
understands a set of commands similar to those of
|
understands a set of commands similar to those of
|
||||||
.Xr ftp 1 .
|
.Xr ftp 1 .
|
||||||
Commands are case insensitive.
|
Commands are case insensitive.
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Ic CD Ar path
|
.It Ic cd Ar path
|
||||||
Change remote directory to
|
Change remote directory to
|
||||||
.Ar path
|
.Ar path .
|
||||||
.It Ic LCD Ar path
|
.It Ic lcd Ar path
|
||||||
Change local directory to
|
Change local directory to
|
||||||
.Ar path
|
.Ar path .
|
||||||
.It Ic CHGRP Ar grp 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.
|
must be a numeric GID.
|
||||||
.It Ic CHMOD Ar mode Ar path
|
.It Ic chmod Ar mode Ar path
|
||||||
Change permissions of file
|
Change permissions of file
|
||||||
.Ar path to
|
.Ar path
|
||||||
.Ar mode
|
to
|
||||||
.It Ic CHOWN Ar own Ar path
|
.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 .
|
||||||
.Ar own
|
.Ar own
|
||||||
must be a numeric UID.
|
must be a numeric UID.
|
||||||
.It Ic HELP
|
.It Ic help
|
||||||
Display help text
|
Display help text.
|
||||||
.It Ic GET Ar remote-file Op Ar local-file
|
.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.
|
and store it on the local machine.
|
||||||
If the local
|
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
|
Display local directory listing of either
|
||||||
.Ar path
|
.Ar path
|
||||||
or current directory if
|
or current directory if
|
||||||
.Ar path
|
.Ar path
|
||||||
was not specified.
|
is not specified.
|
||||||
.It Ic LMKDIR Ar path
|
.It Ic lmkdir Ar path
|
||||||
Create local directory specified by
|
Create local directory specified by
|
||||||
.Ar path
|
.Ar path .
|
||||||
.It Ic LPWD
|
.It Ic lpwd
|
||||||
Print local working directory
|
Print local working directory.
|
||||||
.It Ic LS Op Ar path
|
.It Ic ls Op Ar path
|
||||||
Display remote directory listing of either
|
Display remote directory listing of either
|
||||||
.Ar path
|
.Ar path
|
||||||
or current directory, is
|
or current directory if
|
||||||
.Ar path not specified.
|
|
||||||
.It Ic LUMASK Ar umask
|
|
||||||
Set local umask to
|
|
||||||
.Ar umask
|
|
||||||
.It Ic MKDIR Ar path
|
|
||||||
Create remote directory specified by
|
|
||||||
.Ar path
|
.Ar path
|
||||||
.It Ic PUT local-file Op Ar remote-file
|
is not specified.
|
||||||
|
.It Ic lumask Ar umask
|
||||||
|
Set local umask to
|
||||||
|
.Ar umask .
|
||||||
|
.It Ic mkdir Ar path
|
||||||
|
Create remote directory specified by
|
||||||
|
.Ar path .
|
||||||
|
.It Ic put Ar local-path Op Ar remote-path
|
||||||
Upload
|
Upload
|
||||||
.Ar local-file
|
.Ar local-path
|
||||||
and store it on the remote machine. If the local file name is not specified,
|
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
|
.It Ic pwd
|
||||||
Display remote working directory
|
Display remote working directory.
|
||||||
.It Ic EXIT
|
.It Ic exit
|
||||||
Quit sftp
|
Quit sftp.
|
||||||
.It Ic QUIT
|
.It Ic quit
|
||||||
Quit sftp
|
Quit sftp.
|
||||||
.It Ic RENAME Ar oldpath Ar newpath
|
.It Ic rename Ar oldpath Ar newpath
|
||||||
Rename remote file from
|
Rename remote file from
|
||||||
.Ar oldpath
|
.Ar oldpath
|
||||||
to
|
to
|
||||||
.Ar newpath
|
.Ar newpath .
|
||||||
.It Ic RMDIR Ar path
|
.It Ic rmdir Ar path
|
||||||
Remove remote directory specified by
|
Remove remote directory specified by
|
||||||
.Ar path
|
.Ar path .
|
||||||
.It Ic RM 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
|
.It Ic ! Ar command
|
||||||
Execute
|
Execute
|
||||||
.Ar command
|
.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
|
.Sh AUTHORS
|
||||||
Damien Miller <djm@mindrot.org>
|
Damien Miller <djm@mindrot.org>
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr ssh 1 ,
|
.Xr ssh 1 ,
|
||||||
.Xr ssh-add 1 ,
|
.Xr ssh-add 1 ,
|
||||||
.Xr ssh-keygen 1 ,
|
.Xr ssh-keygen 1 ,
|
||||||
.Xr sshd 8
|
.Xr sshd 8 ,
|
||||||
|
.Xr scp 1
|
||||||
|
|
||||||
|
|
97
sftp.c
97
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: commandline mode */
|
||||||
/* XXX: copy between two remote hosts (commandline) */
|
/* 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-client.h"
|
||||||
#include "sftp-int.h"
|
#include "sftp-int.h"
|
||||||
|
|
||||||
|
int use_ssh1 = 0;
|
||||||
|
char *ssh_program = _PATH_SSH_PROGRAM;
|
||||||
|
char *sftp_server = NULL;
|
||||||
|
|
||||||
void
|
void
|
||||||
connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
|
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(*out);
|
||||||
close(c_in);
|
close(c_in);
|
||||||
close(c_out);
|
close(c_out);
|
||||||
execv(_PATH_SSH_PROGRAM, args);
|
execv(ssh_program, args);
|
||||||
fprintf(stderr, "exec: %s", strerror(errno));
|
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 char **args = NULL;
|
||||||
static int nargs = 0;
|
static int nargs = 0;
|
||||||
char debug_buf[4096];
|
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 */
|
/* Init args array */
|
||||||
if (args == NULL) {
|
if (args == NULL) {
|
||||||
nargs = 4;
|
nargs = use_subsystem ? 6 : 5;
|
||||||
i = 0;
|
i = 0;
|
||||||
args = xmalloc(sizeof(*args) * nargs);
|
args = xmalloc(sizeof(*args) * nargs);
|
||||||
args[i++] = "ssh";
|
args[i++] = "ssh";
|
||||||
args[i++] = "-oProtocol=2";
|
args[i++] = use_ssh1 ? "-oProtocol=1" : "-oProtocol=2";
|
||||||
args[i++] = "-s";
|
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 */
|
/* XXX: overflow - doesn't grow debug_buf */
|
||||||
debug_buf[0] = '\0';
|
debug_buf[0] = '\0';
|
||||||
|
@ -128,49 +143,70 @@ make_ssh_args(char *add_arg)
|
||||||
void
|
void
|
||||||
usage(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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
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"))
|
while ((ch = getopt(argc, argv, "1hvCo:s:S:")) != -1) {
|
||||||
debug_level = MIN(3, debug_level + 1);
|
switch (ch) {
|
||||||
else if (!strcmp(argv[i], "-C"))
|
case 'C':
|
||||||
compress_flag = 1;
|
compress_flag = 1;
|
||||||
else if (!strncmp(argv[i], "-o", 2)) {
|
break;
|
||||||
make_ssh_args(argv[i]);
|
case 'v':
|
||||||
} else {
|
debug_level = MIN(3, debug_level + 1);
|
||||||
fprintf(stderr, "Unknown option \"%s\"\n", argv[i]);
|
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)
|
userhost = argv[optind];
|
||||||
cp = argv[i];
|
|
||||||
|
if ((host = strchr(userhost, '@')) == NULL)
|
||||||
|
host = userhost;
|
||||||
else {
|
else {
|
||||||
*cp = '\0';
|
*host = '\0';
|
||||||
if (!argv[i][0]) {
|
if (!userhost[0]) {
|
||||||
fprintf(stderr, "Missing username\n");
|
fprintf(stderr, "Missing username\n");
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
make_ssh_args("-l");
|
make_ssh_args("-l");
|
||||||
make_ssh_args(argv[i]);
|
make_ssh_args(userhost);
|
||||||
cp++;
|
host++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*cp) {
|
if (!*host) {
|
||||||
fprintf(stderr, "Missing hostname\n");
|
fprintf(stderr, "Missing hostname\n");
|
||||||
usage();
|
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)
|
if (kill(sshpid, SIGHUP) == -1)
|
||||||
fatal("Couldn't terminate ssh process: %s", strerror(errno));
|
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue