mirror of
git://anongit.mindrot.org/openssh.git
synced 2024-11-27 23:53:26 +08:00
- djm@cvs.openbsd.org 2001/03/13 22:42:54
[sftp-client.c sftp-client.h sftp-glob.c sftp-glob.h sftp-int.c] sftp client filename globbing for get, put, ch{mod,grp,own}. ok markus@
This commit is contained in:
parent
056ddf7af3
commit
4870afd7c7
@ -3,6 +3,9 @@
|
||||
- markus@cvs.openbsd.org 2001/03/13 17:34:42
|
||||
[auth-options.c]
|
||||
missing xfree, deny key on parse error; ok stevesk@
|
||||
- djm@cvs.openbsd.org 2001/03/13 22:42:54
|
||||
[sftp-client.c sftp-client.h sftp-glob.c sftp-glob.h sftp-int.c]
|
||||
sftp client filename globbing for get, put, ch{mod,grp,own}. ok markus@
|
||||
|
||||
20010313
|
||||
- OpenBSD CVS Sync
|
||||
@ -4537,4 +4540,4 @@
|
||||
- Wrote replacements for strlcpy and mkdtemp
|
||||
- Released 1.0pre1
|
||||
|
||||
$Id: ChangeLog,v 1.952 2001/03/13 23:15:20 djm Exp $
|
||||
$Id: ChangeLog,v 1.953 2001/03/13 23:27:09 djm Exp $
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.in,v 1.159 2001/03/12 05:16:19 mouring Exp $
|
||||
# $Id: Makefile.in,v 1.160 2001/03/13 23:27:09 djm Exp $
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
@ -116,8 +116,8 @@ ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a log.o ssh-keyscan.o
|
||||
sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o log.o sftp-server.o
|
||||
$(LD) -o $@ sftp-server.o sftp-common.o log.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-int.o sftp-common.o
|
||||
$(LD) -o $@ sftp.o sftp-client.o sftp-common.o sftp-int.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-int.o sftp-common.o sftp-glob.o
|
||||
$(LD) -o $@ sftp.o sftp-client.o sftp-common.o sftp-int.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
# test driver for the loginrec code - not built by default
|
||||
logintest: logintest.o $(LIBCOMPAT) libssh.a log.o loginrec.o
|
||||
|
@ -29,7 +29,7 @@
|
||||
/* XXX: copy between two remote sites */
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sftp-client.c,v 1.11 2001/03/07 10:11:22 djm Exp $");
|
||||
RCSID("$OpenBSD: sftp-client.c,v 1.12 2001/03/13 22:42:54 djm Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "buffer.h"
|
||||
@ -275,11 +275,13 @@ do_close(int fd_in, int fd_out, char *handle, u_int handle_len)
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
do_ls(int fd_in, int fd_out, char *path)
|
||||
do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
|
||||
SFTP_DIRENT ***dir)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int type, id, handle_len, i, expected_id;
|
||||
u_int type, id, handle_len, i, expected_id, ents;
|
||||
char *handle;
|
||||
|
||||
id = msg_id++;
|
||||
@ -296,6 +298,13 @@ do_ls(int fd_in, int fd_out, char *path)
|
||||
if (handle == NULL)
|
||||
return(-1);
|
||||
|
||||
if (dir) {
|
||||
ents = 0;
|
||||
*dir = xmalloc(sizeof(**dir));
|
||||
(*dir)[0] = NULL;
|
||||
}
|
||||
|
||||
|
||||
for(;;) {
|
||||
int count;
|
||||
|
||||
@ -350,7 +359,18 @@ do_ls(int fd_in, int fd_out, char *path)
|
||||
longname = buffer_get_string(&msg, NULL);
|
||||
a = decode_attrib(&msg);
|
||||
|
||||
printf("%s\n", longname);
|
||||
if (printflag)
|
||||
printf("%s\n", longname);
|
||||
|
||||
if (dir) {
|
||||
*dir = xrealloc(*dir, sizeof(**dir) *
|
||||
(ents + 2));
|
||||
(*dir)[ents] = xmalloc(sizeof(***dir));
|
||||
(*dir)[ents]->filename = xstrdup(filename);
|
||||
(*dir)[ents]->longname = xstrdup(longname);
|
||||
memcpy(&(*dir)[ents]->a, a, sizeof(*a));
|
||||
(*dir)[++ents] = NULL;
|
||||
}
|
||||
|
||||
xfree(filename);
|
||||
xfree(longname);
|
||||
@ -364,6 +384,30 @@ do_ls(int fd_in, int fd_out, char *path)
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
do_ls(int fd_in, int fd_out, char *path)
|
||||
{
|
||||
return(do_lsreaddir(fd_in, fd_out, path, 1, NULL));
|
||||
}
|
||||
|
||||
int
|
||||
do_readdir(int fd_in, int fd_out, char *path, SFTP_DIRENT ***dir)
|
||||
{
|
||||
return(do_lsreaddir(fd_in, fd_out, path, 0, dir));
|
||||
}
|
||||
|
||||
void free_sftp_dirents(SFTP_DIRENT **s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; s[i]; i++) {
|
||||
xfree(s[i]->filename);
|
||||
xfree(s[i]->longname);
|
||||
xfree(s[i]);
|
||||
}
|
||||
xfree(s);
|
||||
}
|
||||
|
||||
int
|
||||
do_rm(int fd_in, int fd_out, char *path)
|
||||
{
|
||||
@ -875,3 +919,4 @@ done:
|
||||
buffer_free(&msg);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp-client.h,v 1.2 2001/03/07 10:11:23 djm Exp $ */
|
||||
/* $OpenBSD: sftp-client.h,v 1.3 2001/03/13 22:42:54 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Damien Miller. All rights reserved.
|
||||
@ -26,6 +26,14 @@
|
||||
|
||||
/* Client side of SSH2 filexfer protocol */
|
||||
|
||||
typedef struct SFTP_DIRENT SFTP_DIRENT;
|
||||
|
||||
struct SFTP_DIRENT {
|
||||
char *filename;
|
||||
char *longname;
|
||||
Attrib a;
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialiase a SSH filexfer connection. Returns -1 on error or
|
||||
* protocol version on success.
|
||||
@ -38,6 +46,12 @@ int do_close(int fd_in, int fd_out, char *handle, u_int handle_len);
|
||||
/* List contents of directory 'path' to stdout */
|
||||
int do_ls(int fd_in, int fd_out, char *path);
|
||||
|
||||
/* Read contents of 'path' to NULL-terminated array 'dir' */
|
||||
int do_readdir(int fd_in, int fd_out, char *path, SFTP_DIRENT ***dir);
|
||||
|
||||
/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */
|
||||
void free_sftp_dirents(SFTP_DIRENT **s);
|
||||
|
||||
/* Delete file 'path' */
|
||||
int do_rm(int fd_in, int fd_out, char *path);
|
||||
|
||||
|
160
sftp-glob.c
Normal file
160
sftp-glob.c
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sftp-glob.c,v 1.1 2001/03/13 22:42:54 djm Exp $");
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
#include "ssh.h"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
#include "getput.h"
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
#include "atomicio.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
#include "sftp.h"
|
||||
#include "sftp-common.h"
|
||||
#include "sftp-client.h"
|
||||
#include "sftp-glob.h"
|
||||
|
||||
struct SFTP_OPENDIR {
|
||||
SFTP_DIRENT **dir;
|
||||
int offset;
|
||||
};
|
||||
|
||||
static struct {
|
||||
int fd_in;
|
||||
int fd_out;
|
||||
} cur;
|
||||
|
||||
void *fudge_opendir(const char *path)
|
||||
{
|
||||
struct SFTP_OPENDIR *r;
|
||||
|
||||
r = xmalloc(sizeof(*r));
|
||||
|
||||
if (do_readdir(cur.fd_in, cur.fd_out, (char*)path, &r->dir))
|
||||
return(NULL);
|
||||
|
||||
r->offset = 0;
|
||||
|
||||
return((void*)r);
|
||||
}
|
||||
|
||||
struct dirent *fudge_readdir(struct SFTP_OPENDIR *od)
|
||||
{
|
||||
static struct dirent ret;
|
||||
#ifdef __GNU_LIBRARY__
|
||||
static int inum = 1;
|
||||
#endif /* __GNU_LIBRARY__ */
|
||||
|
||||
if (od->dir[od->offset] == NULL)
|
||||
return(NULL);
|
||||
|
||||
memset(&ret, 0, sizeof(ret));
|
||||
strlcpy(ret.d_name, od->dir[od->offset++]->filename,
|
||||
sizeof(ret.d_name));
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/*
|
||||
* Idiot glibc uses extensions to struct dirent for readdir with
|
||||
* ALTDIRFUNCs. Not that this is documented anywhere but the
|
||||
* source... Fake an inode number to appease it.
|
||||
*/
|
||||
ret.d_ino = inum++;
|
||||
if (!inum)
|
||||
inum = 1;
|
||||
#endif /* __GNU_LIBRARY__ */
|
||||
|
||||
return(&ret);
|
||||
}
|
||||
|
||||
void fudge_closedir(struct SFTP_OPENDIR *od)
|
||||
{
|
||||
free_sftp_dirents(od->dir);
|
||||
free(od);
|
||||
}
|
||||
|
||||
void attrib_to_stat(Attrib *a, struct stat *st)
|
||||
{
|
||||
memset(st, 0, sizeof(*st));
|
||||
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
|
||||
st->st_size = a->size;
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
|
||||
st->st_uid = a->uid;
|
||||
st->st_gid = a->gid;
|
||||
}
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
|
||||
st->st_mode = a->perm;
|
||||
if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
|
||||
st->st_atime = a->atime;
|
||||
st->st_mtime = a->mtime;
|
||||
}
|
||||
}
|
||||
|
||||
int fudge_lstat(const char *path, struct stat *st)
|
||||
{
|
||||
Attrib *a;
|
||||
|
||||
if (!(a = do_lstat(cur.fd_in, cur.fd_out, (char*)path)))
|
||||
return(-1);
|
||||
|
||||
attrib_to_stat(a, st);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int fudge_stat(const char *path, struct stat *st)
|
||||
{
|
||||
Attrib *a;
|
||||
|
||||
if (!(a = do_stat(cur.fd_in, cur.fd_out, (char*)path)))
|
||||
return(-1);
|
||||
|
||||
attrib_to_stat(a, st);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
remote_glob(int fd_in, int fd_out, const char *pattern, int flags,
|
||||
const int (*errfunc)(const char *, int), glob_t *pglob)
|
||||
{
|
||||
pglob->gl_opendir = (void*)fudge_opendir;
|
||||
pglob->gl_readdir = (void*)fudge_readdir;
|
||||
pglob->gl_closedir = (void*)fudge_closedir;
|
||||
pglob->gl_lstat = fudge_lstat;
|
||||
pglob->gl_stat = fudge_stat;
|
||||
|
||||
memset(&cur, 0, sizeof(cur));
|
||||
cur.fd_in = fd_in;
|
||||
cur.fd_out = fd_out;
|
||||
|
||||
return(glob(pattern, flags | GLOB_ALTDIRFUNC, (void*)errfunc,
|
||||
pglob));
|
||||
}
|
32
sftp-glob.h
Normal file
32
sftp-glob.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* $OpenBSD: sftp-glob.h,v 1.1 2001/03/13 22:42:54 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Remote sftp filename globbing */
|
||||
|
||||
int
|
||||
remote_glob(int fd_in, int fd_out, const char *pattern, int flags,
|
||||
const int (*errfunc)(const char *, int), glob_t *pglob);
|
||||
|
133
sftp-int.c
133
sftp-int.c
@ -22,13 +22,13 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* 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.26 2001/03/07 10:11:23 djm Exp $");
|
||||
RCSID("$OpenBSD: sftp-int.c,v 1.27 2001/03/13 22:42:54 djm Exp $");
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "xmalloc.h"
|
||||
@ -37,6 +37,7 @@ RCSID("$OpenBSD: sftp-int.c,v 1.26 2001/03/07 10:11:23 djm Exp $");
|
||||
|
||||
#include "sftp.h"
|
||||
#include "sftp-common.h"
|
||||
#include "sftp-glob.h"
|
||||
#include "sftp-client.h"
|
||||
#include "sftp-int.h"
|
||||
|
||||
@ -283,8 +284,6 @@ infer_path(const char *p, char **ifp)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
debug("XXX: P = \"%s\"", p);
|
||||
|
||||
cp = strrchr(p, '/');
|
||||
if (cp == NULL) {
|
||||
*ifp = xstrdup(p);
|
||||
@ -360,9 +359,6 @@ parse_args(const char **cpp, int *pflag, unsigned long *n_arg,
|
||||
/* Try to get second pathname (optional) */
|
||||
if (get_pathname(&cp, path2))
|
||||
return(-1);
|
||||
/* Otherwise try to guess it from first path */
|
||||
if (*path2 == NULL && infer_path(*path1, path2))
|
||||
return(-1);
|
||||
break;
|
||||
case I_RENAME:
|
||||
case I_SYMLINK:
|
||||
@ -451,11 +447,12 @@ int
|
||||
parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
||||
{
|
||||
char *path1, *path2, *tmp;
|
||||
int pflag, cmdnum;
|
||||
int pflag, cmdnum, i;
|
||||
unsigned long n_arg;
|
||||
Attrib a, *aa;
|
||||
char path_buf[MAXPATHLEN];
|
||||
int err = 0;
|
||||
glob_t g;
|
||||
|
||||
path1 = path2 = NULL;
|
||||
cmdnum = parse_args(&cmd, &pflag, &n_arg, &path1, &path2);
|
||||
@ -465,14 +462,63 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
||||
case -1:
|
||||
break;
|
||||
case I_GET:
|
||||
path1 = make_absolute(path1, *pwd);
|
||||
err = do_download(in, out, path1, path2, pflag);
|
||||
memset(&g, 0, sizeof(g));
|
||||
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;
|
||||
case I_PUT:
|
||||
path2 = make_absolute(path2, *pwd);
|
||||
err = do_upload(in, out, path1, path2, pflag);
|
||||
break;
|
||||
case I_RENAME:
|
||||
if (!glob(path1, 0, NULL, &g)) {
|
||||
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;
|
||||
case I_RENAME:
|
||||
path1 = make_absolute(path1, *pwd);
|
||||
path2 = make_absolute(path2, *pwd);
|
||||
err = do_rename(in, out, path1, path2);
|
||||
@ -489,7 +535,12 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
||||
break;
|
||||
case I_RM:
|
||||
path1 = make_absolute(path1, *pwd);
|
||||
err = do_rm(in, out, path1);
|
||||
remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
|
||||
for(i = 0; g.gl_pathv[i]; i++) {
|
||||
printf("Removing %s\n", g.gl_pathv[i]);
|
||||
if (do_rm(in, out, g.gl_pathv[i]) == -1)
|
||||
err = -1;
|
||||
}
|
||||
break;
|
||||
case I_MKDIR:
|
||||
path1 = make_absolute(path1, *pwd);
|
||||
@ -577,33 +628,45 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
|
||||
attrib_clear(&a);
|
||||
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
|
||||
a.perm = n_arg;
|
||||
do_setstat(in, out, path1, &a);
|
||||
remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
|
||||
for(i = 0; g.gl_pathv[i]; i++) {
|
||||
printf("Changing mode on %s\n", g.gl_pathv[i]);
|
||||
do_setstat(in, out, g.gl_pathv[i], &a);
|
||||
}
|
||||
break;
|
||||
case I_CHOWN:
|
||||
path1 = make_absolute(path1, *pwd);
|
||||
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;
|
||||
remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
|
||||
for(i = 0; g.gl_pathv[i]; i++) {
|
||||
if (!(aa = do_stat(in, out, g.gl_pathv[i])))
|
||||
continue;
|
||||
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
|
||||
error("Can't get current ownership of "
|
||||
"remote file \"%s\"", g.gl_pathv[i]);
|
||||
continue;
|
||||
}
|
||||
printf("Changing owner on %s\n", g.gl_pathv[i]);
|
||||
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
|
||||
aa->uid = n_arg;
|
||||
do_setstat(in, out, g.gl_pathv[i], aa);
|
||||
}
|
||||
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);
|
||||
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;
|
||||
remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
|
||||
for(i = 0; g.gl_pathv[i]; i++) {
|
||||
if (!(aa = do_stat(in, out, g.gl_pathv[i])))
|
||||
continue;
|
||||
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
|
||||
error("Can't get current ownership of "
|
||||
"remote file \"%s\"", g.gl_pathv[i]);
|
||||
continue;
|
||||
}
|
||||
printf("Changing group on %s\n", g.gl_pathv[i]);
|
||||
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
|
||||
aa->gid = n_arg;
|
||||
do_setstat(in, out, g.gl_pathv[i], aa);
|
||||
}
|
||||
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
|
||||
aa->gid = n_arg;
|
||||
do_setstat(in, out, path1, aa);
|
||||
break;
|
||||
case I_PWD:
|
||||
printf("Remote working directory: %s\n", *pwd);
|
||||
|
Loading…
Reference in New Issue
Block a user