- (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
diff --git a/sftp-int.c b/sftp-int.c
index 02e0d38..8b5ae3a 100644
--- a/sftp-int.c
+++ b/sftp-int.c
@@ -24,10 +24,11 @@
/* XXX: finish implementation of all commands */
/* XXX: do fnmatch() instead of using raw pathname */
+/* XXX: globbed ls */
/* XXX: recursive operations */
#include "includes.h"
-RCSID("$OpenBSD: sftp-int.c,v 1.7 2001/02/05 00:02:32 deraadt Exp $");
+RCSID("$OpenBSD: sftp-int.c,v 1.19 2001/02/09 11:46:24 djm Exp $");
#include "buffer.h"
#include "xmalloc.h"
@@ -70,28 +71,29 @@
};
const struct CMD cmds[] = {
- { "CD", I_CHDIR },
- { "CHDIR", I_CHDIR },
- { "CHGRP", I_CHGRP },
- { "CHMOD", I_CHMOD },
- { "CHOWN", I_CHOWN },
- { "EXIT", I_QUIT },
- { "GET", I_GET },
- { "HELP", I_HELP },
- { "LCD", I_LCHDIR },
- { "LCHDIR", I_LCHDIR },
- { "LLS", I_LLS },
- { "LMKDIR", I_LMKDIR },
- { "LPWD", I_LPWD },
- { "LS", I_LS },
- { "LUMASK", I_LUMASK },
- { "MKDIR", I_MKDIR },
- { "PUT", I_PUT },
- { "PWD", I_PWD },
- { "QUIT", I_QUIT },
- { "RENAME", I_RENAME },
- { "RM", I_RM },
- { "RMDIR", I_RMDIR },
+ { "cd", I_CHDIR },
+ { "chdir", I_CHDIR },
+ { "chgrp", I_CHGRP },
+ { "chmod", I_CHMOD },
+ { "chown", I_CHOWN },
+ { "dir", I_LS },
+ { "exit", I_QUIT },
+ { "get", I_GET },
+ { "help", I_HELP },
+ { "lcd", I_LCHDIR },
+ { "lchdir", I_LCHDIR },
+ { "lls", I_LLS },
+ { "lmkdir", I_LMKDIR },
+ { "lpwd", I_LPWD },
+ { "ls", I_LS },
+ { "lumask", I_LUMASK },
+ { "mkdir", I_MKDIR },
+ { "put", I_PUT },
+ { "pwd", I_PWD },
+ { "quit", I_QUIT },
+ { "rename", I_RENAME },
+ { "rm", I_RM },
+ { "rmdir", I_RMDIR },
{ "!", I_SHELL },
{ "?", I_HELP },
{ NULL, -1}
@@ -101,28 +103,29 @@
help(void)
{
printf("Available commands:\n");
- printf("CD path Change remote directory to 'path'\n");
- printf("LCD path Change local directory to 'path'\n");
- printf("CHGRP grp path Change group of file 'path' to 'grp'\n");
- printf("CHMOD mode path Change permissions of file 'path' to 'mode'\n");
- printf("CHOWN own path Change owner of file 'path' to 'own'\n");
- printf("HELP Display this help text\n");
- printf("GET remote-path [local-path] Download file\n");
- printf("LLS [ls options] [path] Display local directory listing\n");
- printf("LMKDIR path Create local directory\n");
- printf("LPWD Print local working directory\n");
- printf("LS [path] Display remote directory listing\n");
- printf("LUMASK umask Set local umask to 'umask'\n");
- printf("MKDIR path Create remote directory\n");
- printf("PUT local-path [remote-path] Upload file\n");
- printf("PWD Display remote working directory\n");
- printf("EXIT Quit sftp\n");
- printf("QUIT Quit sftp\n");
- printf("RENAME oldpath newpath Rename remote file\n");
- printf("RMDIR path Remove remote directory\n");
- printf("RM path Delete remote file\n");
+ printf("cd path Change remote directory to 'path'\n");
+ printf("lcd path Change local directory to 'path'\n");
+ printf("chgrp grp path Change group of file 'path' to 'grp'\n");
+ printf("chmod mode path Change permissions of file 'path' to 'mode'\n");
+ printf("chown own path Change owner of file 'path' to 'own'\n");
+ printf("help Display this help text\n");
+ printf("get remote-path [local-path] Download file\n");
+ printf("lls [ls-options [path]] Display local directory listing\n");
+ printf("lmkdir path Create local directory\n");
+ printf("lpwd Print local working directory\n");
+ printf("ls [path] Display remote directory listing\n");
+ printf("lumask umask Set local umask to 'umask'\n");
+ printf("mkdir path Create remote directory\n");
+ printf("put local-path [remote-path] Upload file\n");
+ printf("pwd Display remote working directory\n");
+ printf("exit Quit sftp\n");
+ printf("quit Quit sftp\n");
+ printf("rename oldpath newpath Rename remote file\n");
+ printf("rmdir path Remove remote directory\n");
+ printf("rm path Delete remote file\n");
printf("!command Execute 'command' in local shell\n");
printf("! Escape to local shell\n");
+ printf("? Synonym for help\n");
}
void
@@ -166,13 +169,15 @@
local_do_ls(const char *args)
{
if (!args || !*args)
- local_do_shell("ls");
+ local_do_shell(_PATH_LS);
else {
- char *buf = xmalloc(8 + strlen(args) + 1);
+ int len = strlen(_PATH_LS " ") + strlen(args) + 1;
+ char *buf = xmalloc(len);
/* XXX: quoting - rip quoting code from ftp? */
- sprintf(buf, "/bin/ls %s", args);
+ snprintf(buf, len, _PATH_LS " %s", args);
local_do_shell(buf);
+ xfree(buf);
}
}
@@ -198,7 +203,7 @@
/* Check for flags */
if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) {
- switch (*cp) {
+ switch (cp[1]) {
case 'P':
*pflag = 1;
break;
@@ -216,50 +221,49 @@
int
get_pathname(const char **cpp, char **path)
{
- const char *quot, *cp = *cpp;
+ const char *cp = *cpp, *end;
+ char quot;
int i;
cp += strspn(cp, WHITESPACE);
if (!*cp) {
*cpp = cp;
*path = NULL;
- return(0);
+ return (0);
}
/* Check for quoted filenames */
if (*cp == '\"' || *cp == '\'') {
- quot = cp++;
- for(i = 0; cp[i] && cp[i] != *quot; i++)
- ;
- if (!cp[i]) {
+ quot = *cp++;
+
+ end = strchr(cp, quot);
+ if (end == NULL) {
error("Unterminated quote");
- *path = NULL;
- return(-1);
+ goto fail;
}
- if (i == 0) {
+ if (cp == end) {
error("Empty quotes");
- *path = NULL;
- return(-1);
+ goto fail;
}
- *path = xmalloc(i + 1);
- memcpy(*path, cp, i);
- (*path)[i] = '\0';
- cp += i + 1;
- *cpp = cp + strspn(cp, WHITESPACE);
- return(0);
+ *cpp = end + 1 + strspn(end + 1, WHITESPACE);
+ } else {
+ /* Read to end of filename */
+ end = strpbrk(cp, WHITESPACE);
+ if (end == NULL)
+ end = strchr(cp, '\0');
+ *cpp = end + strspn(end, WHITESPACE);
}
- /* Read to end of filename */
- for(i = 0; cp[i] && cp[i] != ' '; i++)
- ;
+ i = end - cp;
*path = xmalloc(i + 1);
memcpy(*path, cp, i);
(*path)[i] = '\0';
- cp += i;
- *cpp = cp + strspn(cp, WHITESPACE);
-
return(0);
+
+ fail:
+ *path = NULL;
+ return (-1);
}
int
@@ -270,7 +274,6 @@
debug("XXX: P = \"%s\"", p);
cp = strrchr(p, '/');
-
if (cp == NULL) {
*ifp = xstrdup(p);
return(0);
@@ -421,14 +424,13 @@
}
*cpp = cp;
-
return(cmdnum);
}
int
parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
{
- char *path1, *path2;
+ char *path1, *path2, *tmp;
int pflag, cmdnum;
unsigned long n_arg;
Attrib a, *aa;
@@ -471,12 +473,44 @@
break;
case I_CHDIR:
path1 = make_absolute(path1, *pwd);
+ if ((tmp = do_realpath(in, out, path1)) == NULL)
+ break;
+ if ((aa = do_stat(in, out, tmp)) == NULL) {
+ xfree(tmp);
+ break;
+ }
+ if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
+ error("Can't change directory: Can't check target");
+ xfree(tmp);
+ break;
+ }
+ if (!S_ISDIR(aa->perm)) {
+ error("Can't change directory: \"%s\" is not "
+ "a directory", tmp);
+ xfree(tmp);
+ break;
+ }
xfree(*pwd);
- *pwd = do_realpath(in, out, path1);
+ *pwd = tmp;
break;
case I_LS:
+ if (!path1) {
+ do_ls(in, out, *pwd);
+ break;
+ }
path1 = make_absolute(path1, *pwd);
- do_ls(in, out, path1?path1:*pwd);
+ if ((tmp = do_realpath(in, out, path1)) == NULL)
+ break;
+ xfree(path1);
+ path1 = tmp;
+ if ((aa = do_stat(in, out, path1)) == NULL)
+ break;
+ if ((aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
+ !S_ISDIR(aa->perm)) {
+ error("Can't ls: \"%s\" is not a directory", path1);
+ break;
+ }
+ do_ls(in, out, path1);
break;
case I_LCHDIR:
if (chdir(path1) == -1)
@@ -485,7 +519,7 @@
break;
case I_LMKDIR:
if (mkdir(path1, 0777) == -1)
- error("Couldn't create local directory to "
+ error("Couldn't create local directory "
"\"%s\": %s", path1, strerror(errno));
break;
case I_LLS:
@@ -506,23 +540,27 @@
break;
case I_CHOWN:
path1 = make_absolute(path1, *pwd);
- aa = do_stat(in, out, path1);
+ if (!(aa = do_stat(in, out, path1)))
+ break;
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
error("Can't get current ownership of "
"remote file \"%s\"", path1);
break;
}
+ aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
aa->uid = n_arg;
do_setstat(in, out, path1, aa);
break;
case I_CHGRP:
path1 = make_absolute(path1, *pwd);
- aa = do_stat(in, out, path1);
+ if (!(aa = do_stat(in, out, path1)))
+ break;
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
error("Can't get current ownership of "
"remote file \"%s\"", path1);
break;
}
+ aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
aa->gid = n_arg;
do_setstat(in, out, path1, aa);
break;
@@ -550,7 +588,6 @@
xfree(path1);
if (path2)
xfree(path2);
-
return(0);
}
@@ -564,8 +601,8 @@
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;