mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-27 15:54:22 +02:00
- djm@cvs.openbsd.org 2001/03/16 08:16:18
[sftp-client.c sftp-client.h sftp-glob.c sftp-int.c] Revise globbing for get/put to be more shell-like. In particular, "get/put file* directory/" now works. ok markus@
This commit is contained in:
parent
86fe8686b9
commit
c8d1c30c31
@ -8,6 +8,10 @@
|
|||||||
- markus@cvs.openbsd.org 2001/03/15 22:07:08
|
- markus@cvs.openbsd.org 2001/03/15 22:07:08
|
||||||
[session.c]
|
[session.c]
|
||||||
pass Session to do_child + KNF
|
pass Session to do_child + KNF
|
||||||
|
- djm@cvs.openbsd.org 2001/03/16 08:16:18
|
||||||
|
[sftp-client.c sftp-client.h sftp-glob.c sftp-int.c]
|
||||||
|
Revise globbing for get/put to be more shell-like. In particular,
|
||||||
|
"get/put file* directory/" now works. ok markus@
|
||||||
|
|
||||||
20010315
|
20010315
|
||||||
- OpenBSD CVS Sync
|
- OpenBSD CVS Sync
|
||||||
@ -4570,4 +4574,4 @@
|
|||||||
- Wrote replacements for strlcpy and mkdtemp
|
- Wrote replacements for strlcpy and mkdtemp
|
||||||
- Released 1.0pre1
|
- Released 1.0pre1
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.963 2001/03/17 00:32:57 mouring Exp $
|
$Id: ChangeLog,v 1.964 2001/03/17 00:34:46 mouring Exp $
|
||||||
|
@ -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.13 2001/03/14 08:57:14 markus Exp $");
|
RCSID("$OpenBSD: sftp-client.c,v 1.14 2001/03/16 08:16:17 djm Exp $");
|
||||||
|
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
@ -180,7 +180,7 @@ get_handle(int fd, u_int expected_id, u_int *len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Attrib *
|
Attrib *
|
||||||
get_decode_stat(int fd, u_int expected_id)
|
get_decode_stat(int fd, u_int expected_id, int quiet)
|
||||||
{
|
{
|
||||||
Buffer msg;
|
Buffer msg;
|
||||||
u_int type, id;
|
u_int type, id;
|
||||||
@ -198,6 +198,9 @@ get_decode_stat(int fd, u_int expected_id)
|
|||||||
if (type == SSH2_FXP_STATUS) {
|
if (type == SSH2_FXP_STATUS) {
|
||||||
int status = buffer_get_int(&msg);
|
int status = buffer_get_int(&msg);
|
||||||
|
|
||||||
|
if (quiet)
|
||||||
|
debug("Couldn't stat remote file: %s", fx2txt(status));
|
||||||
|
else
|
||||||
error("Couldn't stat remote file: %s", fx2txt(status));
|
error("Couldn't stat remote file: %s", fx2txt(status));
|
||||||
return(NULL);
|
return(NULL);
|
||||||
} else if (type != SSH2_FXP_ATTRS) {
|
} else if (type != SSH2_FXP_ATTRS) {
|
||||||
@ -455,34 +458,33 @@ do_rmdir(int fd_in, int fd_out, char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Attrib *
|
Attrib *
|
||||||
do_stat(int fd_in, int fd_out, char *path)
|
do_stat(int fd_in, int fd_out, char *path, int quiet)
|
||||||
{
|
{
|
||||||
u_int id;
|
u_int id;
|
||||||
|
|
||||||
id = msg_id++;
|
id = msg_id++;
|
||||||
send_string_request(fd_out, id, SSH2_FXP_STAT, path, strlen(path));
|
send_string_request(fd_out, id, SSH2_FXP_STAT, path, strlen(path));
|
||||||
return(get_decode_stat(fd_in, id));
|
return(get_decode_stat(fd_in, id, quiet));
|
||||||
}
|
}
|
||||||
|
|
||||||
Attrib *
|
Attrib *
|
||||||
do_lstat(int fd_in, int fd_out, char *path)
|
do_lstat(int fd_in, int fd_out, char *path, int quiet)
|
||||||
{
|
{
|
||||||
u_int id;
|
u_int id;
|
||||||
|
|
||||||
id = msg_id++;
|
id = msg_id++;
|
||||||
send_string_request(fd_out, id, SSH2_FXP_LSTAT, path, strlen(path));
|
send_string_request(fd_out, id, SSH2_FXP_LSTAT, path, strlen(path));
|
||||||
return(get_decode_stat(fd_in, id));
|
return(get_decode_stat(fd_in, id, quiet));
|
||||||
}
|
}
|
||||||
|
|
||||||
Attrib *
|
Attrib *
|
||||||
do_fstat(int fd_in, int fd_out, char *handle,
|
do_fstat(int fd_in, int fd_out, char *handle, u_int handle_len, int quiet)
|
||||||
u_int handle_len)
|
|
||||||
{
|
{
|
||||||
u_int id;
|
u_int id;
|
||||||
|
|
||||||
id = msg_id++;
|
id = msg_id++;
|
||||||
send_string_request(fd_out, id, SSH2_FXP_FSTAT, handle, handle_len);
|
send_string_request(fd_out, id, SSH2_FXP_FSTAT, handle, handle_len);
|
||||||
return(get_decode_stat(fd_in, id));
|
return(get_decode_stat(fd_in, id, quiet));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -677,7 +679,7 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
|
|||||||
Attrib junk, *a;
|
Attrib junk, *a;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
a = do_stat(fd_in, fd_out, remote_path);
|
a = do_stat(fd_in, fd_out, remote_path, 0);
|
||||||
if (a == NULL)
|
if (a == NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
@ -687,11 +689,17 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
|
|||||||
else
|
else
|
||||||
mode = 0666;
|
mode = 0666;
|
||||||
|
|
||||||
|
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
|
||||||
|
(a->perm & S_IFDIR)) {
|
||||||
|
error("Cannot download a directory: %s", remote_path);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, mode);
|
local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, mode);
|
||||||
if (local_fd == -1) {
|
if (local_fd == -1) {
|
||||||
error("Couldn't open local file \"%s\" for writing: %s",
|
error("Couldn't open local file \"%s\" for writing: %s",
|
||||||
local_path, strerror(errno));
|
local_path, strerror(errno));
|
||||||
return(errno);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_init(&msg);
|
buffer_init(&msg);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: sftp-client.h,v 1.3 2001/03/13 22:42:54 djm Exp $ */
|
/* $OpenBSD: sftp-client.h,v 1.4 2001/03/16 08:16:18 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001 Damien Miller. All rights reserved.
|
* Copyright (c) 2001 Damien Miller. All rights reserved.
|
||||||
@ -62,14 +62,14 @@ int do_mkdir(int fd_in, int fd_out, char *path, Attrib *a);
|
|||||||
int do_rmdir(int fd_in, int fd_out, char *path);
|
int do_rmdir(int fd_in, int fd_out, char *path);
|
||||||
|
|
||||||
/* Get file attributes of 'path' (follows symlinks) */
|
/* Get file attributes of 'path' (follows symlinks) */
|
||||||
Attrib *do_stat(int fd_in, int fd_out, char *path);
|
Attrib *do_stat(int fd_in, int fd_out, char *path, int quiet);
|
||||||
|
|
||||||
/* Get file attributes of 'path' (does not follow symlinks) */
|
/* Get file attributes of 'path' (does not follow symlinks) */
|
||||||
Attrib *do_lstat(int fd_in, int fd_out, char *path);
|
Attrib *do_lstat(int fd_in, int fd_out, char *path, int quiet);
|
||||||
|
|
||||||
/* Get file attributes of open file 'handle' */
|
/* Get file attributes of open file 'handle' */
|
||||||
Attrib *do_fstat(int fd_in, int fd_out, char *handle,
|
Attrib *do_fstat(int fd_in, int fd_out, char *handle, u_int handle_len,
|
||||||
u_int handle_len);
|
int quiet);
|
||||||
|
|
||||||
/* Set file attributes of 'path' */
|
/* Set file attributes of 'path' */
|
||||||
int do_setstat(int fd_in, int fd_out, char *path, Attrib *a);
|
int do_setstat(int fd_in, int fd_out, char *path, Attrib *a);
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sftp-glob.c,v 1.1 2001/03/13 22:42:54 djm Exp $");
|
RCSID("$OpenBSD: sftp-glob.c,v 1.2 2001/03/16 08:16:18 djm Exp $");
|
||||||
|
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
@ -119,7 +119,7 @@ int fudge_lstat(const char *path, struct stat *st)
|
|||||||
{
|
{
|
||||||
Attrib *a;
|
Attrib *a;
|
||||||
|
|
||||||
if (!(a = do_lstat(cur.fd_in, cur.fd_out, (char*)path)))
|
if (!(a = do_lstat(cur.fd_in, cur.fd_out, (char*)path, 0)))
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
attrib_to_stat(a, st);
|
attrib_to_stat(a, st);
|
||||||
@ -131,7 +131,7 @@ int fudge_stat(const char *path, struct stat *st)
|
|||||||
{
|
{
|
||||||
Attrib *a;
|
Attrib *a;
|
||||||
|
|
||||||
if (!(a = do_stat(cur.fd_in, cur.fd_out, (char*)path)))
|
if (!(a = do_stat(cur.fd_in, cur.fd_out, (char*)path, 0)))
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
attrib_to_stat(a, st);
|
attrib_to_stat(a, st);
|
||||||
|
288
sftp-int.c
288
sftp-int.c
@ -26,7 +26,7 @@
|
|||||||
/* XXX: recursive operations */
|
/* XXX: recursive operations */
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sftp-int.c,v 1.28 2001/03/14 15:15:58 markus Exp $");
|
RCSID("$OpenBSD: sftp-int.c,v 1.29 2001/03/16 08:16:18 djm Exp $");
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
@ -194,19 +194,51 @@ local_do_ls(const char *args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
path_append(char *p1, char *p2)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
ret = xmalloc(strlen(p1) + strlen(p2) + 2);
|
||||||
|
strcpy(ret, p1);
|
||||||
|
strcat(ret, "/");
|
||||||
|
strcat(ret, p2);
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
make_absolute(char *p, char *pwd)
|
make_absolute(char *p, char *pwd)
|
||||||
{
|
{
|
||||||
char buf[2048];
|
char *abs;
|
||||||
|
|
||||||
/* Derelativise */
|
/* Derelativise */
|
||||||
if (p && p[0] != '/') {
|
if (p && p[0] != '/') {
|
||||||
snprintf(buf, sizeof(buf), "%s/%s", pwd, p);
|
abs = path_append(pwd, p);
|
||||||
xfree(p);
|
xfree(p);
|
||||||
p = xstrdup(buf);
|
return(abs);
|
||||||
|
} else
|
||||||
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(p);
|
int
|
||||||
|
infer_path(const char *p, char **ifp)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
cp = strrchr(p, '/');
|
||||||
|
if (cp == NULL) {
|
||||||
|
*ifp = xstrdup(p);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cp[1]) {
|
||||||
|
error("Invalid path");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
*ifp = xstrdup(cp + 1);
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -281,23 +313,182 @@ get_pathname(const char **cpp, char **path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
infer_path(const char *p, char **ifp)
|
is_dir(char *path)
|
||||||
{
|
{
|
||||||
char *cp;
|
struct stat sb;
|
||||||
|
|
||||||
cp = strrchr(p, '/');
|
/* XXX: report errors? */
|
||||||
if (cp == NULL) {
|
if (stat(path, &sb) == -1)
|
||||||
*ifp = xstrdup(p);
|
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
return(sb.st_mode & S_IFDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cp[1]) {
|
int
|
||||||
error("Invalid path");
|
remote_is_dir(int in, int out, char *path)
|
||||||
return(-1);
|
{
|
||||||
|
Attrib *a;
|
||||||
|
|
||||||
|
/* XXX: report errors? */
|
||||||
|
if ((a = do_stat(in, out, path, 1)) == NULL)
|
||||||
|
return(0);
|
||||||
|
if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
|
||||||
|
return(0);
|
||||||
|
return(a->perm & S_IFDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
*ifp = xstrdup(cp + 1);
|
int
|
||||||
return(0);
|
process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
|
||||||
|
{
|
||||||
|
char *abs_src = NULL;
|
||||||
|
char *abs_dst = NULL;
|
||||||
|
char *tmp;
|
||||||
|
glob_t g;
|
||||||
|
int err = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
abs_src = xstrdup(src);
|
||||||
|
abs_src = make_absolute(abs_src, pwd);
|
||||||
|
|
||||||
|
memset(&g, '\0', sizeof(g));
|
||||||
|
debug3("Looking up %s", abs_src);
|
||||||
|
if (remote_glob(in, out, abs_src, 0, NULL, &g)) {
|
||||||
|
error("File \"%s\" not found.", abs_src);
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only one match, dst may be file, directory or unspecified */
|
||||||
|
if (g.gl_pathv[0] && g.gl_matchc == 1) {
|
||||||
|
if (dst) {
|
||||||
|
/* If directory specified, append filename */
|
||||||
|
if (is_dir(dst)) {
|
||||||
|
if (infer_path(g.gl_pathv[0], &tmp)) {
|
||||||
|
err = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
abs_dst = path_append(dst, tmp);
|
||||||
|
xfree(tmp);
|
||||||
|
} else
|
||||||
|
abs_dst = xstrdup(dst);
|
||||||
|
} else if (infer_path(g.gl_pathv[0], &abs_dst)) {
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst);
|
||||||
|
err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Multiple matches, dst may be directory or unspecified */
|
||||||
|
if (dst && !is_dir(dst)) {
|
||||||
|
error("Multiple files match, but \"%s\" is not a directory",
|
||||||
|
dst);
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; g.gl_pathv[i]; i++) {
|
||||||
|
if (infer_path(g.gl_pathv[i], &tmp)) {
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (dst) {
|
||||||
|
abs_dst = path_append(dst, tmp);
|
||||||
|
xfree(tmp);
|
||||||
|
} else
|
||||||
|
abs_dst = tmp;
|
||||||
|
|
||||||
|
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
|
||||||
|
if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
|
||||||
|
err = -1;
|
||||||
|
xfree(abs_dst);
|
||||||
|
abs_dst = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
xfree(abs_src);
|
||||||
|
if (abs_dst)
|
||||||
|
xfree(abs_dst);
|
||||||
|
globfree(&g);
|
||||||
|
return(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
|
||||||
|
{
|
||||||
|
char *tmp_dst = NULL;
|
||||||
|
char *abs_dst = NULL;
|
||||||
|
char *tmp;
|
||||||
|
glob_t g;
|
||||||
|
int err = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (dst) {
|
||||||
|
tmp_dst = xstrdup(dst);
|
||||||
|
tmp_dst = make_absolute(tmp_dst, pwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&g, '\0', sizeof(g));
|
||||||
|
debug3("Looking up %s", src);
|
||||||
|
if (glob(src, 0, NULL, &g)) {
|
||||||
|
error("File \"%s\" not found.", src);
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only one match, dst may be file, directory or unspecified */
|
||||||
|
if (g.gl_pathv[0] && g.gl_matchc == 1) {
|
||||||
|
if (tmp_dst) {
|
||||||
|
/* If directory specified, append filename */
|
||||||
|
if (remote_is_dir(in, out, tmp_dst)) {
|
||||||
|
if (infer_path(g.gl_pathv[0], &tmp)) {
|
||||||
|
err = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
abs_dst = path_append(tmp_dst, tmp);
|
||||||
|
xfree(tmp);
|
||||||
|
} else
|
||||||
|
abs_dst = xstrdup(tmp_dst);
|
||||||
|
} else if (infer_path(g.gl_pathv[0], &abs_dst)) {
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst);
|
||||||
|
err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Multiple matches, dst may be directory or unspecified */
|
||||||
|
if (tmp_dst && !remote_is_dir(in, out, tmp_dst)) {
|
||||||
|
error("Multiple files match, but \"%s\" is not a directory",
|
||||||
|
tmp_dst);
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; g.gl_pathv[i]; i++) {
|
||||||
|
if (infer_path(g.gl_pathv[i], &tmp)) {
|
||||||
|
err = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (tmp_dst) {
|
||||||
|
abs_dst = path_append(tmp_dst, tmp);
|
||||||
|
xfree(tmp);
|
||||||
|
} else
|
||||||
|
abs_dst = make_absolute(tmp, pwd);
|
||||||
|
|
||||||
|
printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
|
||||||
|
if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
|
||||||
|
err = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (abs_dst)
|
||||||
|
xfree(abs_dst);
|
||||||
|
if (tmp_dst)
|
||||||
|
xfree(tmp_dst);
|
||||||
|
return(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -459,66 +650,17 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
|||||||
path1 = path2 = NULL;
|
path1 = path2 = NULL;
|
||||||
cmdnum = parse_args(&cmd, &pflag, &n_arg, &path1, &path2);
|
cmdnum = parse_args(&cmd, &pflag, &n_arg, &path1, &path2);
|
||||||
|
|
||||||
|
memset(&g, 0, sizeof(g));
|
||||||
|
|
||||||
/* Perform command */
|
/* Perform command */
|
||||||
switch (cmdnum) {
|
switch (cmdnum) {
|
||||||
case -1:
|
case -1:
|
||||||
break;
|
break;
|
||||||
case I_GET:
|
case I_GET:
|
||||||
memset(&g, 0, sizeof(g));
|
err = process_get(in, out, path1, path2, *pwd, pflag);
|
||||||
if (!remote_glob(in, out, path1, 0, NULL, &g)) {
|
|
||||||
if (path2) {
|
|
||||||
/* XXX: target should be directory */
|
|
||||||
error("You cannot specify a target when "
|
|
||||||
"downloading multiple files");
|
|
||||||
err = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for(i = 0; g.gl_pathv[i]; i++) {
|
|
||||||
if (!infer_path(g.gl_pathv[i], &path2)) {
|
|
||||||
printf("Fetching %s\n", g.gl_pathv[i]);
|
|
||||||
if (do_download(in, out, g.gl_pathv[i],
|
|
||||||
path2, pflag) == -1)
|
|
||||||
err = -1;
|
|
||||||
free(path2);
|
|
||||||
path2 = NULL;
|
|
||||||
} else
|
|
||||||
err = -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!path2 && infer_path(path1, &path2)) {
|
|
||||||
err = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err = do_download(in, out, path1, path2, pflag);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case I_PUT:
|
case I_PUT:
|
||||||
if (!glob(path1, 0, NULL, &g)) {
|
err = process_put(in, out, path1, path2, *pwd, pflag);
|
||||||
if (path2) {
|
|
||||||
error("You cannot specify a target when "
|
|
||||||
"uploading multiple files");
|
|
||||||
err = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for(i = 0; g.gl_pathv[i]; i++) {
|
|
||||||
if (!infer_path(g.gl_pathv[i], &path2)) {
|
|
||||||
path2 = make_absolute(path2, *pwd);
|
|
||||||
printf("Uploading %s\n", g.gl_pathv[i]);
|
|
||||||
if (do_upload(in, out, g.gl_pathv[i],
|
|
||||||
path2, pflag) == -1)
|
|
||||||
err = -1;
|
|
||||||
free(path2);
|
|
||||||
path2 = NULL;
|
|
||||||
} else
|
|
||||||
err = -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!path2 && infer_path(path1, &path2)) {
|
|
||||||
err = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err = do_upload(in, out, path1, path2, pflag);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case I_RENAME:
|
case I_RENAME:
|
||||||
path1 = make_absolute(path1, *pwd);
|
path1 = make_absolute(path1, *pwd);
|
||||||
@ -561,7 +703,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
|||||||
err = 1;
|
err = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((aa = do_stat(in, out, tmp)) == NULL) {
|
if ((aa = do_stat(in, out, tmp, 0)) == NULL) {
|
||||||
xfree(tmp);
|
xfree(tmp);
|
||||||
err = 1;
|
err = 1;
|
||||||
break;
|
break;
|
||||||
@ -592,7 +734,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
|||||||
break;
|
break;
|
||||||
xfree(path1);
|
xfree(path1);
|
||||||
path1 = tmp;
|
path1 = tmp;
|
||||||
if ((aa = do_stat(in, out, path1)) == NULL)
|
if ((aa = do_stat(in, out, path1, 0)) == NULL)
|
||||||
break;
|
break;
|
||||||
if ((aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
|
if ((aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
|
||||||
!S_ISDIR(aa->perm)) {
|
!S_ISDIR(aa->perm)) {
|
||||||
@ -640,7 +782,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
|||||||
path1 = make_absolute(path1, *pwd);
|
path1 = make_absolute(path1, *pwd);
|
||||||
remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
|
remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
|
||||||
for(i = 0; g.gl_pathv[i]; i++) {
|
for(i = 0; g.gl_pathv[i]; i++) {
|
||||||
if (!(aa = do_stat(in, out, g.gl_pathv[i])))
|
if (!(aa = do_stat(in, out, g.gl_pathv[i], 0)))
|
||||||
continue;
|
continue;
|
||||||
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 "
|
||||||
@ -657,7 +799,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
|||||||
path1 = make_absolute(path1, *pwd);
|
path1 = make_absolute(path1, *pwd);
|
||||||
remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
|
remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
|
||||||
for(i = 0; g.gl_pathv[i]; i++) {
|
for(i = 0; g.gl_pathv[i]; i++) {
|
||||||
if (!(aa = do_stat(in, out, g.gl_pathv[i])))
|
if (!(aa = do_stat(in, out, g.gl_pathv[i], 0)))
|
||||||
continue;
|
continue;
|
||||||
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 "
|
||||||
@ -693,6 +835,8 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
|||||||
fatal("%d is not implemented", cmdnum);
|
fatal("%d is not implemented", cmdnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g.gl_pathc)
|
||||||
|
globfree(&g);
|
||||||
if (path1)
|
if (path1)
|
||||||
xfree(path1);
|
xfree(path1);
|
||||||
if (path2)
|
if (path2)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user