* change usage to ssshfs user@host:path mountpath
* assorted little fixes ssshfs now works for practical uses
This commit is contained in:
parent
d6bc4d2b49
commit
5676e026f8
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: sftp-connect.c,v 1.1 2006/11/21 00:54:06 pooka Exp $ */
|
/* $NetBSD: sftp-connect.c,v 1.2 2006/11/21 23:09:23 pooka Exp $ */
|
||||||
|
|
||||||
/* NetBSD: sftp.c,v 1.21 2006/09/28 21:22:15 christos Exp */
|
/* NetBSD: sftp.c,v 1.21 2006/09/28 21:22:15 christos Exp */
|
||||||
/* $OpenBSD: sftp.c,v 1.91 2006/08/03 03:34:42 deraadt Exp $ */
|
/* $OpenBSD: sftp.c,v 1.91 2006/08/03 03:34:42 deraadt Exp $ */
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
__RCSID("$NetBSD: sftp-connect.c,v 1.1 2006/11/21 00:54:06 pooka Exp $");
|
__RCSID("$NetBSD: sftp-connect.c,v 1.2 2006/11/21 23:09:23 pooka Exp $");
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
@ -147,12 +147,13 @@ sftp_main(int argc, char **argv)
|
||||||
extern int in, out;
|
extern int in, out;
|
||||||
char *host, *userhost, *cp, *file2 = NULL;
|
char *host, *userhost, *cp, *file2 = NULL;
|
||||||
int debug_level = 0, sshver = 2;
|
int debug_level = 0, sshver = 2;
|
||||||
char *file1 = NULL, *sftp_server = NULL;
|
char *sftp_server = NULL;
|
||||||
char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
|
char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
|
||||||
LogLevel ll = SYSLOG_LEVEL_INFO;
|
LogLevel ll = SYSLOG_LEVEL_INFO;
|
||||||
arglist args;
|
arglist args;
|
||||||
extern int optind;
|
extern int optind;
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
|
extern char *argpath;
|
||||||
|
|
||||||
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
|
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
|
||||||
sanitise_stdfd();
|
sanitise_stdfd();
|
||||||
|
@ -255,7 +256,7 @@ sftp_main(int argc, char **argv)
|
||||||
|
|
||||||
if ((cp = colon(host)) != NULL) {
|
if ((cp = colon(host)) != NULL) {
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
file1 = cp;
|
argpath = cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
host = cleanhostname(host);
|
host = cleanhostname(host);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: sftp-getput.c,v 1.1 2006/11/21 00:54:06 pooka Exp $ */
|
/* $NetBSD: sftp-getput.c,v 1.2 2006/11/21 23:09:23 pooka Exp $ */
|
||||||
|
|
||||||
/* NetBSD: sftp-client.c,v 1.26 2006/09/28 21:22:15 christos Exp */
|
/* NetBSD: sftp-client.c,v 1.26 2006/09/28 21:22:15 christos Exp */
|
||||||
/* $OpenBSD: sftp-client.c,v 1.74 2006/08/03 03:34:42 deraadt Exp $ */
|
/* $OpenBSD: sftp-client.c,v 1.74 2006/08/03 03:34:42 deraadt Exp $ */
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
/* XXX: copy between two remote sites */
|
/* XXX: copy between two remote sites */
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
__RCSID("$NetBSD: sftp-getput.c,v 1.1 2006/11/21 00:54:06 pooka Exp $");
|
__RCSID("$NetBSD: sftp-getput.c,v 1.2 2006/11/21 23:09:23 pooka Exp $");
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
@ -429,7 +429,7 @@ do_readfile(struct sftp_conn *conn, char *path, uint8_t *localbuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
do_writefile(struct sftp_conn *conn, const char *path, uint8_t *localbuf,
|
do_writefile(struct sftp_conn *conn, char *path, uint8_t *localbuf,
|
||||||
off_t putoff, size_t *putlen, int append)
|
off_t putoff, size_t *putlen, int append)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
@ -437,7 +437,8 @@ do_writefile(struct sftp_conn *conn, const char *path, uint8_t *localbuf,
|
||||||
u_int64_t offset;
|
u_int64_t offset;
|
||||||
char *handle, *data;
|
char *handle, *data;
|
||||||
Buffer msg;
|
Buffer msg;
|
||||||
Attrib a;
|
Attrib a, savea;
|
||||||
|
Attrib *ap;
|
||||||
u_int32_t startid;
|
u_int32_t startid;
|
||||||
u_int32_t ackid;
|
u_int32_t ackid;
|
||||||
struct outstanding_ack {
|
struct outstanding_ack {
|
||||||
|
@ -451,11 +452,20 @@ do_writefile(struct sftp_conn *conn, const char *path, uint8_t *localbuf,
|
||||||
|
|
||||||
TAILQ_INIT(&acks);
|
TAILQ_INIT(&acks);
|
||||||
|
|
||||||
|
/* XXX: temporarily set file permission to allow writing */
|
||||||
|
ap = do_stat(conn, path, 1);
|
||||||
|
if (!ap)
|
||||||
|
return -1;
|
||||||
|
memcpy(&savea, ap, sizeof(Attrib));
|
||||||
|
savea.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
|
||||||
|
|
||||||
memset(&a, 0, sizeof(a));
|
memset(&a, 0, sizeof(a));
|
||||||
a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
|
a.flags = SSH2_FILEXFER_ATTR_PERMISSIONS;
|
||||||
a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
|
a.perm = 0777;
|
||||||
a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
|
if (do_setstat(conn, path, &a)) {
|
||||||
a.perm &= 0777;
|
printf("lossage\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
buffer_init(&msg);
|
buffer_init(&msg);
|
||||||
|
|
||||||
|
@ -473,6 +483,7 @@ do_writefile(struct sftp_conn *conn, const char *path, uint8_t *localbuf,
|
||||||
|
|
||||||
handle = get_handle(conn->fd_in, id, &handle_len);
|
handle = get_handle(conn->fd_in, id, &handle_len);
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
|
do_setstat(conn, path, &savea);
|
||||||
buffer_free(&msg);
|
buffer_free(&msg);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
@ -559,6 +570,7 @@ do_writefile(struct sftp_conn *conn, const char *path, uint8_t *localbuf,
|
||||||
*putlen -= (offset - putoff);
|
*putlen -= (offset - putoff);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
do_setstat(conn, path, &savea);
|
||||||
xfree(handle);
|
xfree(handle);
|
||||||
buffer_free(&msg);
|
buffer_free(&msg);
|
||||||
return(status);
|
return(status);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: ssshfs.c,v 1.5 2006/11/21 15:35:58 pooka Exp $ */
|
/* $NetBSD: ssshfs.c,v 1.6 2006/11/21 23:09:23 pooka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006 Antti Kantee. All Rights Reserved.
|
* Copyright (c) 2006 Antti Kantee. All Rights Reserved.
|
||||||
|
@ -55,7 +55,7 @@ PUFFSVN_PROTOS(ssshfs)
|
||||||
|
|
||||||
struct ssshnode {
|
struct ssshnode {
|
||||||
struct ssshnode *dotdot;
|
struct ssshnode *dotdot;
|
||||||
int refcount;
|
int childcount;
|
||||||
ino_t myid;
|
ino_t myid;
|
||||||
|
|
||||||
char name[MAXPATHLEN+1];
|
char name[MAXPATHLEN+1];
|
||||||
|
@ -66,17 +66,19 @@ struct ssshnode {
|
||||||
|
|
||||||
struct vattr va;
|
struct vattr va;
|
||||||
};
|
};
|
||||||
|
#define DCACHE_EXISTS 0x1
|
||||||
|
#define DCACHE_CHANGED 0x2
|
||||||
|
|
||||||
static struct sftp_conn *sftpc;
|
static struct sftp_conn *sftpc;
|
||||||
int in, out;
|
int in, out;
|
||||||
|
|
||||||
static char *basepath;
|
|
||||||
|
|
||||||
static struct ssshnode rn;
|
static struct ssshnode rn;
|
||||||
static ino_t nextid = 3;
|
static ino_t nextid = 3;
|
||||||
|
|
||||||
extern int sftp_main(int argc, char *argv[]);
|
extern int sftp_main(int argc, char *argv[]);
|
||||||
|
|
||||||
|
char *argpath; /* XXX: arg passing nightmare */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* uberquickhack one-person uidgid-mangler in case the target
|
* uberquickhack one-person uidgid-mangler in case the target
|
||||||
* system doesn't have the same uids and gids
|
* system doesn't have the same uids and gids
|
||||||
|
@ -95,8 +97,8 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
setprogname(argv[0]);
|
setprogname(argv[0]);
|
||||||
|
|
||||||
if (argc < 4)
|
if (argc < 3)
|
||||||
errx(1, "usage: %s mountpath hostpath user@host",getprogname());
|
errx(1, "usage: %s user@host:path mountpath", getprogname());
|
||||||
|
|
||||||
memset(&pvfs, 0, sizeof(struct puffs_vfsops));
|
memset(&pvfs, 0, sizeof(struct puffs_vfsops));
|
||||||
memset(&pvn, 0, sizeof(struct puffs_vnops));
|
memset(&pvn, 0, sizeof(struct puffs_vnops));
|
||||||
|
@ -121,14 +123,12 @@ main(int argc, char *argv[])
|
||||||
pvn.puffs_rename = ssshfs_rename;
|
pvn.puffs_rename = ssshfs_rename;
|
||||||
pvn.puffs_reclaim = ssshfs_reclaim;
|
pvn.puffs_reclaim = ssshfs_reclaim;
|
||||||
|
|
||||||
mountpath = argv[1];
|
mountpath = argv[--argc]; /* urgh */
|
||||||
basepath = estrdup(argv[2]);
|
|
||||||
argv += 2;
|
|
||||||
argc -= 2;
|
|
||||||
|
|
||||||
sftp_main(argc, argv);
|
sftp_main(argc, argv);
|
||||||
|
|
||||||
if ((pu = puffs_mount(&pvfs, &pvn, mountpath, 0, "ssshfs", 0, 0))==NULL)
|
if ((pu = puffs_mount(&pvfs, &pvn, mountpath, 0, "ssshfs",
|
||||||
|
PUFFSFLAG_NOCACHE, 0))==NULL)
|
||||||
err(1, "mount");
|
err(1, "mount");
|
||||||
|
|
||||||
if (puffs_mainloop(pu) == -1)
|
if (puffs_mainloop(pu) == -1)
|
||||||
|
@ -186,24 +186,37 @@ vattrtoAttrib(const struct vattr *va)
|
||||||
{
|
{
|
||||||
static Attrib a; /* XXX, but sftp isn't threadsafe either */
|
static Attrib a; /* XXX, but sftp isn't threadsafe either */
|
||||||
|
|
||||||
a.size = va->va_size;
|
memset(&a, 0, sizeof(a));
|
||||||
|
|
||||||
if (va->va_uid == uidmangle_from && mangle)
|
if (va->va_size != PUFFS_VNOVAL) {
|
||||||
a.uid = uidmangle_to;
|
a.size = va->va_size;
|
||||||
else
|
a.flags |= SSH2_FILEXFER_ATTR_SIZE;
|
||||||
a.uid = va->va_uid;
|
}
|
||||||
|
|
||||||
if (va->va_gid == gidmangle_from && mangle)
|
if (va->va_uid != PUFFS_VNOVAL) {
|
||||||
a.gid = gidmangle_to;
|
if (va->va_uid == uidmangle_from && mangle)
|
||||||
else
|
a.uid = uidmangle_to;
|
||||||
a.gid = va->va_gid;
|
else
|
||||||
|
a.uid = va->va_uid;
|
||||||
|
|
||||||
a.perm = va->va_mode;
|
if (va->va_gid == gidmangle_from && mangle)
|
||||||
a.atime = va->va_atime.tv_sec;
|
a.gid = gidmangle_to;
|
||||||
a.mtime = va->va_mtime.tv_sec;
|
else
|
||||||
|
a.gid = va->va_gid;
|
||||||
|
|
||||||
a.flags = SSH2_FILEXFER_ATTR_SIZE | SSH2_FILEXFER_ATTR_UIDGID
|
a.flags |= SSH2_FILEXFER_ATTR_UIDGID;
|
||||||
| SSH2_FILEXFER_ATTR_PERMISSIONS | SSH2_FILEXFER_ATTR_ACMODTIME;
|
}
|
||||||
|
|
||||||
|
if (va->va_mode != PUFFS_VNOVAL) {
|
||||||
|
a.perm = va->va_mode & 0777;
|
||||||
|
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (va->va_atime.tv_sec != PUFFS_VNOVAL) {
|
||||||
|
a.atime = va->va_atime.tv_sec;
|
||||||
|
a.mtime = va->va_mtime.tv_sec;
|
||||||
|
a.flags |= SSH2_FILEXFER_ATTR_ACMODTIME;
|
||||||
|
}
|
||||||
|
|
||||||
return &a;
|
return &a;
|
||||||
}
|
}
|
||||||
|
@ -214,13 +227,19 @@ dircache(struct ssshnode *ssn)
|
||||||
|
|
||||||
assert(ssn->va.va_type == VDIR);
|
assert(ssn->va.va_type == VDIR);
|
||||||
|
|
||||||
if (ssn->dcache)
|
if ((ssn->dcache & DCACHE_EXISTS)
|
||||||
|
&& ((ssn->dcache & DCACHE_CHANGED) == 0))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ssn->dcache & DCACHE_EXISTS)
|
||||||
free_sftp_dirents(ssn->ents);
|
free_sftp_dirents(ssn->ents);
|
||||||
ssn->dcache = 0;
|
ssn->dcache &= ~DCACHE_EXISTS;
|
||||||
|
|
||||||
if (do_readdir(sftpc, ssn->name, &ssn->ents) != 0)
|
if (do_readdir(sftpc, ssn->name, &ssn->ents) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
ssn->dcache = 1;
|
|
||||||
|
ssn->dcache |= DCACHE_EXISTS;
|
||||||
|
ssn->dcache &= ~DCACHE_CHANGED;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -239,10 +258,12 @@ makenewnode(struct ssshnode *ossn, const char *pcomp, const char *longname)
|
||||||
|
|
||||||
buildpath(newssn, ossn, pcomp);
|
buildpath(newssn, ossn, pcomp);
|
||||||
|
|
||||||
ossn->refcount++;
|
ossn->childcount++;
|
||||||
newssn->refcount = 1;
|
newssn->childcount = 0;
|
||||||
newssn->va.va_fileid = newssn->myid;
|
newssn->va.va_fileid = newssn->myid;
|
||||||
newssn->va.va_blocksize = 512;
|
newssn->va.va_blocksize = 512;
|
||||||
|
newssn->va.va_size = 0;
|
||||||
|
newssn->va.va_bytes = 0;
|
||||||
|
|
||||||
/* XXX: only way I know how (didn't look into the protocol, though) */
|
/* XXX: only way I know how (didn't look into the protocol, though) */
|
||||||
if (longname && (sscanf(longname, "%*s%d", &links) == 1))
|
if (longname && (sscanf(longname, "%*s%d", &links) == 1))
|
||||||
|
@ -257,22 +278,32 @@ int
|
||||||
ssshfs_mount(struct puffs_usermount *pu, void **rootcookie)
|
ssshfs_mount(struct puffs_usermount *pu, void **rootcookie)
|
||||||
{
|
{
|
||||||
|
|
||||||
rn.refcount = 1;
|
|
||||||
rn.myid = 2;
|
|
||||||
|
|
||||||
memset(rn.name, 0, sizeof(rn.name));
|
|
||||||
strcpy(rn.name, basepath);
|
|
||||||
rn.namelen = strlen(rn.name);
|
|
||||||
|
|
||||||
rn.va.va_type = VDIR;
|
|
||||||
rn.va.va_mode = 0777;
|
|
||||||
|
|
||||||
sftpc = do_init(in, out, 1<<15, 1);
|
sftpc = do_init(in, out, 1<<15, 1);
|
||||||
if (sftpc == NULL) {
|
if (sftpc == NULL) {
|
||||||
printf("can't init sftpc\n");
|
printf("can't init sftpc\n");
|
||||||
return EBUSY;
|
return EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rn.childcount = 1;
|
||||||
|
rn.myid = 2;
|
||||||
|
|
||||||
|
memset(rn.name, 0, sizeof(rn.name));
|
||||||
|
|
||||||
|
if (argpath)
|
||||||
|
strcpy(rn.name, argpath);
|
||||||
|
else {
|
||||||
|
char *dotpath;
|
||||||
|
dotpath = do_realpath(sftpc, ".");
|
||||||
|
if (!dotpath)
|
||||||
|
return ENOENT;
|
||||||
|
strcpy(rn.name, dotpath);
|
||||||
|
}
|
||||||
|
rn.namelen = strlen(rn.name);
|
||||||
|
|
||||||
|
rn.va.va_type = VDIR;
|
||||||
|
rn.va.va_mode = 0777;
|
||||||
|
rn.va.va_nlink = 1024; /* XXXX */
|
||||||
|
|
||||||
*rootcookie = &rn;
|
*rootcookie = &rn;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -303,8 +334,7 @@ ssshfs_lookup(struct puffs_usermount *pu, void *opc, void **newnode,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ssn->dcache)
|
dircache(ssn);
|
||||||
dircache(ssn);
|
|
||||||
|
|
||||||
for (i = 0, de = ssn->ents[0]; de; de = ssn->ents[i++])
|
for (i = 0, de = ssn->ents[0]; de; de = ssn->ents[i++])
|
||||||
if (strcmp(de->filename, pcn->pcn_name) == 0)
|
if (strcmp(de->filename, pcn->pcn_name) == 0)
|
||||||
|
@ -330,7 +360,6 @@ ssshfs_getattr(struct puffs_usermount *pu, void *opc, struct vattr *va,
|
||||||
struct ssshnode *ssn = opc;
|
struct ssshnode *ssn = opc;
|
||||||
|
|
||||||
memcpy(va, &ssn->va, sizeof(struct vattr));
|
memcpy(va, &ssn->va, sizeof(struct vattr));
|
||||||
va->va_type = VREG;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -344,10 +373,12 @@ ssshfs_setattr(struct puffs_usermount *pu, void *opc, const struct vattr *va,
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
puffs_setvattr(&ssn->va, va);
|
puffs_setvattr(&ssn->va, va);
|
||||||
a = vattrtoAttrib(&ssn->va);
|
a = vattrtoAttrib(va);
|
||||||
|
|
||||||
/* XXXXX */
|
/* XXX: compensate for lack of granulatity of SSH2_FILEXFER */
|
||||||
return 0;
|
if ((a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)
|
||||||
|
&& (va->va_mtime.tv_sec == PUFFS_VNOVAL))
|
||||||
|
a->mtime = ssn->va.va_mtime.tv_sec;
|
||||||
|
|
||||||
rv = do_setstat(sftpc, ssn->name, a);
|
rv = do_setstat(sftpc, ssn->name, a);
|
||||||
if (rv)
|
if (rv)
|
||||||
|
@ -366,14 +397,14 @@ ssshfs_create(struct puffs_usermount *pu, void *opc, void **newnode,
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
newssn = makenewnode(ssd, pcn->pcn_name, NULL);
|
newssn = makenewnode(ssd, pcn->pcn_name, NULL);
|
||||||
memcpy(&newssn->va, va, sizeof(struct vattr));
|
puffs_setvattr(&newssn->va, va);
|
||||||
a = vattrtoAttrib(va);
|
a = vattrtoAttrib(va);
|
||||||
if ((rv = do_creatfile(sftpc, newssn->name, a)) != 0) {
|
if ((rv = do_creatfile(sftpc, newssn->name, a)) != 0) {
|
||||||
/* XXX: free newssn */
|
/* XXX: free newssn */
|
||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
dircache(ssd);
|
ssd->dcache |= DCACHE_CHANGED;
|
||||||
ssd->va.va_nlink++;
|
ssd->va.va_nlink++;
|
||||||
|
|
||||||
*newnode = newssn;
|
*newnode = newssn;
|
||||||
|
@ -387,8 +418,7 @@ ssshfs_readdir(struct puffs_usermount *pu, void *opc, struct dirent *dent,
|
||||||
struct ssshnode *ssn = opc;
|
struct ssshnode *ssn = opc;
|
||||||
struct SFTP_DIRENT *de;
|
struct SFTP_DIRENT *de;
|
||||||
|
|
||||||
if (!ssn->dcache)
|
dircache(ssn);
|
||||||
dircache(ssn);
|
|
||||||
|
|
||||||
for (de = ssn->ents[*readoff]; de; de = ssn->ents[++(*readoff)]) {
|
for (de = ssn->ents[*readoff]; de; de = ssn->ents[++(*readoff)]) {
|
||||||
if (!puffs_nextdent(&dent, de->filename, nextid++,
|
if (!puffs_nextdent(&dent, de->filename, nextid++,
|
||||||
|
@ -404,18 +434,27 @@ ssshfs_read(struct puffs_usermount *pu, void *opc, uint8_t *buf,
|
||||||
off_t offset, size_t *resid, const struct puffs_cred *pcr,
|
off_t offset, size_t *resid, const struct puffs_cred *pcr,
|
||||||
int ioflag)
|
int ioflag)
|
||||||
{
|
{
|
||||||
|
size_t x1, x2;
|
||||||
struct ssshnode *ssn = opc;
|
struct ssshnode *ssn = opc;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (offset + *resid > ssn->va.va_size)
|
if (offset > ssn->va.va_size)
|
||||||
*resid = ssn->va.va_size - offset;
|
|
||||||
if (*resid == 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rv = do_readfile(sftpc, ssn->name, buf, offset, resid);
|
x1 = *resid;
|
||||||
|
if (offset + *resid > ssn->va.va_size)
|
||||||
|
x1 = ssn->va.va_size - offset;
|
||||||
|
|
||||||
|
if (x1 == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
x2 = x1;
|
||||||
|
rv = do_readfile(sftpc, ssn->name, buf, offset, &x1);
|
||||||
if (rv)
|
if (rv)
|
||||||
return EIO;
|
return EIO;
|
||||||
|
|
||||||
|
*resid -= (x2 - x1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,8 +481,6 @@ ssshfs_write(struct puffs_usermount *pu, void *opc, uint8_t *buf,
|
||||||
if (rv)
|
if (rv)
|
||||||
return EIO;
|
return EIO;
|
||||||
|
|
||||||
dircache(ssn->dotdot);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,7 +513,7 @@ ssshfs_remove(struct puffs_usermount *pu, void *opc, void *targ,
|
||||||
if ((rv = do_rm(sftpc, ssn->name)) != 0)
|
if ((rv = do_rm(sftpc, ssn->name)) != 0)
|
||||||
return EIO;
|
return EIO;
|
||||||
|
|
||||||
dircache(ssd);
|
ssd->dcache |= DCACHE_CHANGED;
|
||||||
ssd->va.va_nlink--;
|
ssd->va.va_nlink--;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -491,16 +528,16 @@ ssshfs_mkdir(struct puffs_usermount *pu, void *opc, void **newnode,
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
newssn = makenewnode(ssd, pcn->pcn_name, NULL);
|
newssn = makenewnode(ssd, pcn->pcn_name, NULL);
|
||||||
memcpy(&newssn->va, va, sizeof(struct vattr));
|
newssn->va.va_nlink++;
|
||||||
|
puffs_setvattr(&newssn->va, va);
|
||||||
a = vattrtoAttrib(va);
|
a = vattrtoAttrib(va);
|
||||||
if ((rv = do_mkdir(sftpc, newssn->name, a)) != 0) {
|
if ((rv = do_mkdir(sftpc, newssn->name, a)) != 0) {
|
||||||
/* XXX: free newssn */
|
/* XXX: free newssn */
|
||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
dircache(ssd);
|
ssd->dcache |= DCACHE_CHANGED;
|
||||||
ssd->va.va_nlink++;
|
ssd->va.va_nlink++;
|
||||||
newssn->va.va_nlink++;
|
|
||||||
|
|
||||||
*newnode = newssn;
|
*newnode = newssn;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -519,7 +556,7 @@ ssshfs_rmdir(struct puffs_usermount *pu, void *opc, void *targ,
|
||||||
if ((rv = do_rmdir(sftpc, ssn->name)) != 0)
|
if ((rv = do_rmdir(sftpc, ssn->name)) != 0)
|
||||||
return EIO;
|
return EIO;
|
||||||
|
|
||||||
dircache(ssd);
|
ssd->dcache |= DCACHE_CHANGED;
|
||||||
ssd->va.va_nlink--;
|
ssd->va.va_nlink--;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -544,12 +581,12 @@ ssshfs_symlink(struct puffs_usermount *pu, void *opc, void **newnode,
|
||||||
}
|
}
|
||||||
|
|
||||||
newssn = makenewnode(ssd, pcn->pcn_name, NULL);
|
newssn = makenewnode(ssd, pcn->pcn_name, NULL);
|
||||||
memcpy(&newssn->va, va, sizeof(struct vattr));
|
puffs_setvattr(&newssn->va, va);
|
||||||
a = vattrtoAttrib(va);
|
a = vattrtoAttrib(va);
|
||||||
if ((rv = do_symlink(sftpc, newssn->name, buf)) != 0)
|
if ((rv = do_symlink(sftpc, newssn->name, buf)) != 0)
|
||||||
return EIO;
|
return EIO;
|
||||||
|
|
||||||
dircache(ssd);
|
ssd->dcache |= DCACHE_CHANGED;
|
||||||
ssd->va.va_nlink++;
|
ssd->va.va_nlink++;
|
||||||
|
|
||||||
*newnode = newssn;
|
*newnode = newssn;
|
||||||
|
@ -578,13 +615,13 @@ ssshfs_rename(struct puffs_usermount *pu, void *opc, void *src,
|
||||||
|
|
||||||
/* ok, commit */
|
/* ok, commit */
|
||||||
ssn_file->namelen = strlen(newname);
|
ssn_file->namelen = strlen(newname);
|
||||||
ssd_src->refcount--;
|
ssd_src->childcount--;
|
||||||
ssd_src->va.va_nlink--;
|
ssd_src->va.va_nlink--;
|
||||||
ssd_dest->refcount++;
|
ssd_dest->childcount++;
|
||||||
ssd_dest->va.va_nlink++;
|
ssd_dest->va.va_nlink++;
|
||||||
|
|
||||||
dircache(ssd_src);
|
ssd_src->dcache |= DCACHE_CHANGED;
|
||||||
dircache(ssd_dest);
|
ssd_dest->dcache |= DCACHE_CHANGED;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -592,16 +629,18 @@ ssshfs_rename(struct puffs_usermount *pu, void *opc, void *src,
|
||||||
int
|
int
|
||||||
ssshfs_reclaim(struct puffs_usermount *pu, void *opc, pid_t pid)
|
ssshfs_reclaim(struct puffs_usermount *pu, void *opc, pid_t pid)
|
||||||
{
|
{
|
||||||
struct ssshnode *ssn = opc;
|
struct ssshnode *ssn, *ssn_next;
|
||||||
|
|
||||||
/* XXX */
|
for (ssn = opc; ssn != &rn; ssn = ssn_next) {
|
||||||
|
if (ssn->childcount == 0) {
|
||||||
#if 0
|
if (ssn->dcache & DCACHE_EXISTS)
|
||||||
if (--ssn->refcount == 0) {
|
free_sftp_dirents(ssn->ents);
|
||||||
free_sftp_dirents(ssn->ents);
|
ssn_next = ssn->dotdot;
|
||||||
free(ssn);
|
ssn_next->childcount--;
|
||||||
|
free(ssn);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue