diff options
author | Damien Miller <djm@mindrot.org> | 2001-02-10 00:40:03 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2001-02-10 00:40:03 +1100 |
commit | d7686fd1fbe842baa8ce77f018c040d5e1d3438a (patch) | |
tree | a5d6ad5b4b232e06185a49b1b5aabe4761a3d8ed /sftp-int.c | |
parent | 4192c467916f96668fad5b53d90d83dfbfdcacb5 (diff) |
- (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
Diffstat (limited to 'sftp-int.c')
-rw-r--r-- | sftp-int.c | 199 |
1 files changed, 118 insertions, 81 deletions
@@ -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 @@ struct CMD { }; const struct CMD cmds[] = { - { "CD", I_CHDIR }, - { "CHDIR", I_CHDIR }, - { "CHGRP", I_CHGRP }, - { "CHMOD", I_CHMOD }, - { "CHOWN", I_CHOWN }, - { "EXIT", I_QUIT }, - { "GET", I_GET }, - { "HELP", I_HELP }, - { "LCD", I_LCHDIR }, - { "LCHDIR", I_LCHDIR }, - { "LLS", I_LLS }, - { "LMKDIR", I_LMKDIR }, - { "LPWD", I_LPWD }, - { "LS", I_LS }, - { "LUMASK", I_LUMASK }, - { "MKDIR", I_MKDIR }, - { "PUT", I_PUT }, - { "PWD", I_PWD }, - { "QUIT", I_QUIT }, - { "RENAME", I_RENAME }, - { "RM", I_RM }, - { "RMDIR", I_RMDIR }, + { "cd", I_CHDIR }, + { "chdir", I_CHDIR }, + { "chgrp", I_CHGRP }, + { "chmod", I_CHMOD }, + { "chown", I_CHOWN }, + { "dir", I_LS }, + { "exit", I_QUIT }, + { "get", I_GET }, + { "help", I_HELP }, + { "lcd", I_LCHDIR }, + { "lchdir", I_LCHDIR }, + { "lls", I_LLS }, + { "lmkdir", I_LMKDIR }, + { "lpwd", I_LPWD }, + { "ls", I_LS }, + { "lumask", I_LUMASK }, + { "mkdir", I_MKDIR }, + { "put", I_PUT }, + { "pwd", I_PWD }, + { "quit", I_QUIT }, + { "rename", I_RENAME }, + { "rm", I_RM }, + { "rmdir", I_RMDIR }, { "!", I_SHELL }, { "?", I_HELP }, { NULL, -1} @@ -101,28 +103,29 @@ void help(void) { printf("Available commands:\n"); - printf("CD path Change remote directory to 'path'\n"); - printf("LCD path Change local directory to 'path'\n"); - printf("CHGRP grp path Change group of file 'path' to 'grp'\n"); - printf("CHMOD mode path Change permissions of file 'path' to 'mode'\n"); - printf("CHOWN own path Change owner of file 'path' to 'own'\n"); - printf("HELP Display this help text\n"); - printf("GET remote-path [local-path] Download file\n"); - printf("LLS [ls options] [path] Display local directory listing\n"); - printf("LMKDIR path Create local directory\n"); - printf("LPWD Print local working directory\n"); - printf("LS [path] Display remote directory listing\n"); - printf("LUMASK umask Set local umask to 'umask'\n"); - printf("MKDIR path Create remote directory\n"); - printf("PUT local-path [remote-path] Upload file\n"); - printf("PWD Display remote working directory\n"); - printf("EXIT Quit sftp\n"); - printf("QUIT Quit sftp\n"); - printf("RENAME oldpath newpath Rename remote file\n"); - printf("RMDIR path Remove remote directory\n"); - printf("RM path Delete remote file\n"); + printf("cd path Change remote directory to 'path'\n"); + printf("lcd path Change local directory to 'path'\n"); + printf("chgrp grp path Change group of file 'path' to 'grp'\n"); + printf("chmod mode path Change permissions of file 'path' to 'mode'\n"); + printf("chown own path Change owner of file 'path' to 'own'\n"); + printf("help Display this help text\n"); + printf("get remote-path [local-path] Download file\n"); + printf("lls [ls-options [path]] Display local directory listing\n"); + printf("lmkdir path Create local directory\n"); + printf("lpwd Print local working directory\n"); + printf("ls [path] Display remote directory listing\n"); + printf("lumask umask Set local umask to 'umask'\n"); + printf("mkdir path Create remote directory\n"); + printf("put local-path [remote-path] Upload file\n"); + printf("pwd Display remote working directory\n"); + printf("exit Quit sftp\n"); + printf("quit Quit sftp\n"); + printf("rename oldpath newpath Rename remote file\n"); + printf("rmdir path Remove remote directory\n"); + printf("rm path Delete remote file\n"); printf("!command Execute 'command' in local shell\n"); printf("! Escape to local shell\n"); + printf("? Synonym for help\n"); } void @@ -166,13 +169,15 @@ void local_do_ls(const char *args) { if (!args || !*args) - local_do_shell("ls"); + local_do_shell(_PATH_LS); else { - char *buf = xmalloc(8 + strlen(args) + 1); + int len = strlen(_PATH_LS " ") + strlen(args) + 1; + char *buf = xmalloc(len); /* XXX: quoting - rip quoting code from ftp? */ - sprintf(buf, "/bin/ls %s", args); + snprintf(buf, len, _PATH_LS " %s", args); local_do_shell(buf); + xfree(buf); } } @@ -198,7 +203,7 @@ parse_getput_flags(const char **cpp, int *pflag) /* Check for flags */ if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) { - switch (*cp) { + switch (cp[1]) { case 'P': *pflag = 1; break; @@ -216,50 +221,49 @@ parse_getput_flags(const char **cpp, int *pflag) int get_pathname(const char **cpp, char **path) { - const char *quot, *cp = *cpp; + const char *cp = *cpp, *end; + char quot; int i; cp += strspn(cp, WHITESPACE); if (!*cp) { *cpp = cp; *path = NULL; - return(0); + return (0); } /* Check for quoted filenames */ if (*cp == '\"' || *cp == '\'') { - quot = cp++; - for(i = 0; cp[i] && cp[i] != *quot; i++) - ; - if (!cp[i]) { + quot = *cp++; + + end = strchr(cp, quot); + if (end == NULL) { error("Unterminated quote"); - *path = NULL; - return(-1); + goto fail; } - if (i == 0) { + if (cp == end) { error("Empty quotes"); - *path = NULL; - return(-1); + goto fail; } - *path = xmalloc(i + 1); - memcpy(*path, cp, i); - (*path)[i] = '\0'; - cp += i + 1; - *cpp = cp + strspn(cp, WHITESPACE); - return(0); + *cpp = end + 1 + strspn(end + 1, WHITESPACE); + } else { + /* Read to end of filename */ + end = strpbrk(cp, WHITESPACE); + if (end == NULL) + end = strchr(cp, '\0'); + *cpp = end + strspn(end, WHITESPACE); } - /* Read to end of filename */ - for(i = 0; cp[i] && cp[i] != ' '; i++) - ; + i = end - cp; *path = xmalloc(i + 1); memcpy(*path, cp, i); (*path)[i] = '\0'; - cp += i; - *cpp = cp + strspn(cp, WHITESPACE); - return(0); + + fail: + *path = NULL; + return (-1); } int @@ -270,7 +274,6 @@ infer_path(const char *p, char **ifp) debug("XXX: P = \"%s\"", p); cp = strrchr(p, '/'); - if (cp == NULL) { *ifp = xstrdup(p); return(0); @@ -421,14 +424,13 @@ parse_args(const char **cpp, int *pflag, unsigned long *n_arg, } *cpp = cp; - return(cmdnum); } int parse_dispatch_command(int in, int out, const char *cmd, char **pwd) { - char *path1, *path2; + char *path1, *path2, *tmp; int pflag, cmdnum; unsigned long n_arg; Attrib a, *aa; @@ -471,12 +473,44 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd) break; case I_CHDIR: path1 = make_absolute(path1, *pwd); + if ((tmp = do_realpath(in, out, path1)) == NULL) + break; + if ((aa = do_stat(in, out, tmp)) == NULL) { + xfree(tmp); + break; + } + if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) { + error("Can't change directory: Can't check target"); + xfree(tmp); + break; + } + if (!S_ISDIR(aa->perm)) { + error("Can't change directory: \"%s\" is not " + "a directory", tmp); + xfree(tmp); + break; + } xfree(*pwd); - *pwd = do_realpath(in, out, path1); + *pwd = tmp; break; case I_LS: + if (!path1) { + do_ls(in, out, *pwd); + break; + } path1 = make_absolute(path1, *pwd); - do_ls(in, out, path1?path1:*pwd); + if ((tmp = do_realpath(in, out, path1)) == NULL) + break; + xfree(path1); + path1 = tmp; + if ((aa = do_stat(in, out, path1)) == NULL) + break; + if ((aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && + !S_ISDIR(aa->perm)) { + error("Can't ls: \"%s\" is not a directory", path1); + break; + } + do_ls(in, out, path1); break; case I_LCHDIR: if (chdir(path1) == -1) @@ -485,7 +519,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd) break; case I_LMKDIR: if (mkdir(path1, 0777) == -1) - error("Couldn't create local directory to " + error("Couldn't create local directory " "\"%s\": %s", path1, strerror(errno)); break; case I_LLS: @@ -506,23 +540,27 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd) break; case I_CHOWN: path1 = make_absolute(path1, *pwd); - aa = do_stat(in, out, path1); + if (!(aa = do_stat(in, out, path1))) + break; if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { error("Can't get current ownership of " "remote file \"%s\"", path1); break; } + aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; aa->uid = n_arg; do_setstat(in, out, path1, aa); break; case I_CHGRP: path1 = make_absolute(path1, *pwd); - aa = do_stat(in, out, path1); + if (!(aa = do_stat(in, out, path1))) + break; if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { error("Can't get current ownership of " "remote file \"%s\"", path1); break; } + aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; aa->gid = n_arg; do_setstat(in, out, path1, aa); break; @@ -550,7 +588,6 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd) xfree(path1); if (path2) xfree(path2); - return(0); } @@ -564,8 +601,8 @@ interactive_loop(int fd_in, int fd_out) if (pwd == NULL) fatal("Need cwd"); - setvbuf(stdout, (char *)NULL, _IOLBF, 0); - setvbuf(stdin, (char *)NULL, _IOLBF, 0); + setvbuf(stdout, NULL, _IOLBF, 0); + setvbuf(stdin, NULL, _IOLBF, 0); for(;;) { char *cp; |