importing sources

This commit is contained in:
Miklos Szeredi 2004-11-12 22:54:02 +00:00
commit fc170be8c6
2 changed files with 908 additions and 0 deletions

21
Makefile Normal file
View File

@ -0,0 +1,21 @@
CC = gcc
CFLAGS := -Wall -W -g
LDLIBS := -lpthread -ldl -rdynamic
PKGCONFIG := env PKG_CONFIG_PATH=/usr/local/lib/pkgconfig pkg-config
FUSEVER := $(shell $(PKGCONFIG) --modversion fuse 2> /dev/null)
ifeq ($(FUSEVER),)
LDLIBS += -lfuse
else
CFLAGS += $(shell $(PKGCONFIG) --cflags fuse)
LDLIBS += $(shell $(PKGCONFIG) --libs fuse)
endif
CPPFLAGS := -D_FILE_OFFSET_BITS=64
#CPPFLAGS += -DDEBUG
sshfs: sshfs.o
clean:
rm -f *.o sshfs

887
sshfs.c Normal file
View File

@ -0,0 +1,887 @@
#include <fuse.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <netinet/in.h>
#define SSH_FXP_INIT 1
#define SSH_FXP_VERSION 2
#define SSH_FXP_OPEN 3
#define SSH_FXP_CLOSE 4
#define SSH_FXP_READ 5
#define SSH_FXP_WRITE 6
#define SSH_FXP_LSTAT 7
#define SSH_FXP_FSTAT 8
#define SSH_FXP_SETSTAT 9
#define SSH_FXP_FSETSTAT 10
#define SSH_FXP_OPENDIR 11
#define SSH_FXP_READDIR 12
#define SSH_FXP_REMOVE 13
#define SSH_FXP_MKDIR 14
#define SSH_FXP_RMDIR 15
#define SSH_FXP_REALPATH 16
#define SSH_FXP_STAT 17
#define SSH_FXP_RENAME 18
#define SSH_FXP_READLINK 19
#define SSH_FXP_SYMLINK 20
#define SSH_FXP_STATUS 101
#define SSH_FXP_HANDLE 102
#define SSH_FXP_DATA 103
#define SSH_FXP_NAME 104
#define SSH_FXP_ATTRS 105
#define SSH_FXP_EXTENDED 200
#define SSH_FXP_EXTENDED_REPLY 201
#define SSH_FILEXFER_ATTR_SIZE 0x00000001
#define SSH_FILEXFER_ATTR_UIDGID 0x00000002
#define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
#define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008
#define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
#define SSH_FX_OK 0
#define SSH_FX_EOF 1
#define SSH_FX_NO_SUCH_FILE 2
#define SSH_FX_PERMISSION_DENIED 3
#define SSH_FX_FAILURE 4
#define SSH_FX_BAD_MESSAGE 5
#define SSH_FX_NO_CONNECTION 6
#define SSH_FX_CONNECTION_LOST 7
#define SSH_FX_OP_UNSUPPORTED 8
#define SSH_FXF_READ 0x00000001
#define SSH_FXF_WRITE 0x00000002
#define SSH_FXF_APPEND 0x00000004
#define SSH_FXF_CREAT 0x00000008
#define SSH_FXF_TRUNC 0x00000010
#define SSH_FXF_EXCL 0x00000020
#define PROTO_VERSION 3
#define MY_EOF 1
static int infd;
static int outfd;
struct buffer {
uint8_t *p;
size_t len;
size_t size;
};
static inline void buf_init(struct buffer *buf, size_t size)
{
if (size) {
buf->p = malloc(size);
if (!buf->p)
exit(1);
} else
buf->p = NULL;
buf->len = 0;
buf->size = size;
}
static inline void buf_free(struct buffer *buf)
{
free(buf->p);
}
static inline void buf_finish(struct buffer *buf)
{
buf->len = buf->size;
}
static inline void buf_clear(struct buffer *buf)
{
buf_free(buf);
buf_init(buf, 0);
}
static void buf_resize(struct buffer *buf, size_t len)
{
buf->size = (buf->len + len + 63) & ~31;
buf->p = (uint8_t *) realloc(buf->p, buf->size);
if (!buf->p)
exit(1);
}
static inline void buf_check_add(struct buffer *buf, size_t len)
{
if (buf->len + len > buf->size)
buf_resize(buf, len);
}
#define _buf_add_mem(b, d, l) \
buf_check_add(b, l); \
memcpy(b->p + b->len, d, l); \
b->len += l;
static inline void buf_add_mem(struct buffer *buf, const void *data,
size_t len)
{
_buf_add_mem(buf, data, len);
}
static inline void buf_add_uint8(struct buffer *buf, uint8_t val)
{
_buf_add_mem(buf, &val, 1);
}
static inline void buf_add_uint32(struct buffer *buf, uint32_t val)
{
uint32_t nval = htonl(val);
_buf_add_mem(buf, &nval, 4);
}
static inline void buf_add_uint64(struct buffer *buf, uint64_t val)
{
buf_add_uint32(buf, val >> 32);
buf_add_uint32(buf, val & 0xffffffff);
}
static inline void buf_add_data(struct buffer *buf, const struct buffer *data)
{
buf_add_uint32(buf, data->len);
buf_add_mem(buf, data->p, data->len);
}
static inline void buf_add_string(struct buffer *buf, const char *str)
{
struct buffer data;
data.p = (uint8_t *) str;
data.len = strlen(str);
buf_add_data(buf, &data);
}
static int buf_check_get(struct buffer *buf, size_t len)
{
if (buf->len + len > buf->size) {
fprintf(stderr, "buffer too short\n");
return -1;
} else
return 0;
}
static inline int buf_get_mem(struct buffer *buf, void *data, size_t len)
{
if (buf_check_get(buf, len) == -1)
return -1;
memcpy(data, buf->p + buf->len, len);
buf->len += len;
return 0;
}
static inline int buf_get_uint8(struct buffer *buf, uint8_t *val)
{
return buf_get_mem(buf, val, 1);
}
static inline int buf_get_uint32(struct buffer *buf, uint32_t *val)
{
uint32_t nval;
if (buf_get_mem(buf, &nval, 4) == -1)
return -1;
*val = ntohl(nval);
return 0;
}
static inline int buf_get_uint64(struct buffer *buf, uint64_t *val)
{
uint32_t val1;
uint32_t val2;
if (buf_get_uint32(buf, &val1) == -1 || buf_get_uint32(buf, &val2) == -1)
return -1;
*val = ((uint64_t) val1 << 32) + val2;
return 0;
}
static inline int buf_get_data(struct buffer *buf, struct buffer *data)
{
uint32_t len;
if (buf_get_uint32(buf, &len) == -1 || len > buf->size - buf->len)
return -1;
buf_init(data, len + 1);
data->size = len;
if (buf_get_mem(buf, data->p, data->size) == -1) {
buf_free(data);
return -1;
}
return 0;
}
static inline int buf_get_string(struct buffer *buf, char **str)
{
struct buffer data;
if (buf_get_data(buf, &data) == -1)
return -1;
data.p[data.size] = '\0';
*str = (char *) data.p;
return 0;
}
static int buf_get_attrs(struct buffer *buf, struct stat *stbuf)
{
uint32_t flags;
uint64_t size = 0;
uint32_t uid = 0;
uint32_t gid = 0;
uint32_t atime = 0;
uint32_t mtime = 0;
uint32_t mode = S_IFREG | 0777;
if (buf_get_uint32(buf, &flags) == -1)
return -1;
if ((flags & SSH_FILEXFER_ATTR_SIZE) &&
buf_get_uint64(buf, &size) == -1)
return -1;
if ((flags & SSH_FILEXFER_ATTR_UIDGID) &&
(buf_get_uint32(buf, &uid) == -1 ||
buf_get_uint32(buf, &gid) == -1))
return -1;
if ((flags & SSH_FILEXFER_ATTR_PERMISSIONS) &&
buf_get_uint32(buf, &mode) == -1)
return -1;
if ((flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
if (buf_get_uint32(buf, &atime) == -1 ||
buf_get_uint32(buf, &mtime) == -1)
return -1;
}
if ((flags & SSH_FILEXFER_ATTR_EXTENDED)) {
uint32_t extcount;
unsigned i;
if (buf_get_uint32(buf, &extcount) == -1)
return -1;
for (i = 0; i < extcount; i++) {
struct buffer tmp;
if (buf_get_data(buf, &tmp) == -1)
return -1;
buf_free(&tmp);
if (buf_get_data(buf, &tmp) == -1)
return -1;
buf_free(&tmp);
}
}
memset(stbuf, 0, sizeof(struct stat));
stbuf->st_mode = mode;
stbuf->st_nlink = 1;
stbuf->st_size = size;
stbuf->st_uid = uid;
stbuf->st_gid = gid;
stbuf->st_atime = atime;
stbuf->st_mtime = mtime;
return 0;
}
static int buf_get_entries(struct buffer *buf, fuse_dirh_t h,
fuse_dirfil_t filler)
{
uint32_t count;
unsigned i;
if (buf_get_uint32(buf, &count) == -1)
return -1;
for (i = 0; i < count; i++) {
int err = -1;
char *name;
char *longname;
struct stat stbuf;
if (buf_get_string(buf, &name) == -1)
return -1;
if (buf_get_string(buf, &longname) != -1) {
free(longname);
if (buf_get_attrs(buf, &stbuf) != -1) {
filler(h, name, stbuf.st_mode >> 12);
err = 0;
}
}
free(name);
if (err)
return err;
}
return 0;
}
static int start_ssh(const char *host)
{
int inpipe[2];
int outpipe[2];
int pid;
if (pipe(inpipe) == -1 || pipe(outpipe) == -1) {
perror("failed to create pipe");
return -1;
}
infd = inpipe[0];
outfd = outpipe[1];
pid = fork();
if (pid == -1) {
perror("failed to fork");
return -1;
} else if (pid == 0) {
if (dup2(outpipe[0], 0) == -1 || dup2(inpipe[1], 1) == -1) {
perror("failed to redirect input/output");
exit(1);
}
close(inpipe[0]);
close(inpipe[1]);
close(outpipe[0]);
close(outpipe[1]);
execlp("ssh", "ssh", "-2", "-x", "-a", "-oClearAllForwardings=yes",
host, "-s", "sftp", NULL);
exit(1);
}
close(inpipe[1]);
close(outpipe[0]);
return 0;
}
static int do_write(struct buffer *buf)
{
uint8_t *p = buf->p;
size_t size = buf->len;
int res;
while (size) {
res = write(outfd, p, size);
if (res == -1) {
perror("write");
return -1;
} else if (res == 0) {
fprintf(stderr, "zero write\n");
return -1;
}
size -= res;
p += res;
}
return 0;
}
static uint32_t sftp_get_id(void)
{
static uint32_t idctr;
return idctr++;
}
static int sftp_send(uint8_t type, struct buffer *buf)
{
int res;
struct buffer buf2;
buf_init(&buf2, 5);
buf_add_uint32(&buf2, buf->len + 1);
buf_add_uint8(&buf2, type);
res = do_write(&buf2);
if (res != -1)
res = do_write(buf);
buf_free(&buf2);
return res;
}
static int do_read(struct buffer *buf)
{
int res;
uint8_t *p = buf->p;
size_t size = buf->size;
while (size) {
res = read(infd, p, size);
if (res == -1) {
perror("read");
return -1;
} else if (res == 0) {
fprintf(stderr, "end of file read\n");
return -1;
}
size -= res;
p += res;
}
return 0;
}
static int sftp_read(uint8_t *type, struct buffer *buf)
{
int res;
struct buffer buf2;
uint32_t len;
buf_init(&buf2, 5);
res = do_read(&buf2);
if (res != -1) {
buf_get_uint32(&buf2, &len);
buf_get_uint8(&buf2, type);
buf_init(buf, len - 1);
res = do_read(buf);
}
buf_free(&buf2);
return res;
}
static int sftp_request(uint8_t type, const struct buffer *buf,
uint8_t expect_type, struct buffer *outbuf)
{
int err;
struct buffer buf2;
uint32_t id = sftp_get_id();
uint32_t idback;
uint8_t typeback;
buf_init(&buf2, buf->len + 4);
buf_add_uint32(&buf2, id);
buf_add_mem(&buf2, buf->p, buf->len);
err = -EIO;
if (sftp_send(type, &buf2) == -1)
goto out;
buf_clear(&buf2);
if (sftp_read(&typeback, &buf2) == -1)
goto out;
err = -EPROTO;
if (typeback != expect_type && typeback != SSH_FXP_STATUS) {
fprintf(stderr, "protocol error\n");
goto out;
}
if (buf_get_uint32(&buf2, &idback) == -1)
goto out;
if (idback != id) {
fprintf(stderr, "Invalid ID received\n");
goto out;
}
if (typeback == SSH_FXP_STATUS) {
uint32_t serr;
if (buf_get_uint32(&buf2, &serr) == -1)
goto out;
switch (serr) {
case SSH_FX_OK:
if (expect_type == SSH_FXP_STATUS)
err = 0;
else
err = -EPROTO;
break;
case SSH_FX_EOF:
if (type == SSH_FXP_READ || type == SSH_FXP_READDIR)
err = MY_EOF;
else
err = -EPROTO;
break;
case SSH_FX_NO_SUCH_FILE: err = -ENOENT; break;
case SSH_FX_PERMISSION_DENIED: err = -EACCES; break;
case SSH_FX_FAILURE: err = -EPERM; break;
case SSH_FX_BAD_MESSAGE:
default: err = -EPROTO; break;
}
} else {
buf_init(outbuf, buf2.size - buf2.len);
buf_get_mem(&buf2, outbuf->p, outbuf->size);
err = 0;
}
out:
buf_free(&buf2);
return err;
}
static int sshfs_getattr(const char *path, struct stat *stbuf)
{
int err;
struct buffer buf;
struct buffer outbuf;
buf_init(&buf, 0);
buf_add_string(&buf, path);
err = sftp_request(SSH_FXP_LSTAT, &buf, SSH_FXP_ATTRS, &outbuf);
if (!err) {
if (buf_get_attrs(&outbuf, stbuf) == -1)
err = -EPROTO;
buf_free(&outbuf);
}
buf_free(&buf);
return err;
}
static int sshfs_readlink(const char *path, char *linkbuf, size_t size)
{
int err;
struct buffer buf;
struct buffer name;
buf_init(&buf, 0);
buf_add_string(&buf, path);
err = sftp_request(SSH_FXP_READLINK, &buf, SSH_FXP_NAME, &name);
if (!err) {
uint32_t count;
char *link;
err = -EPROTO;
if(buf_get_uint32(&name, &count) != -1 && count == 1 &&
buf_get_string(&name, &link) != -1) {
strncpy(linkbuf, link, size-1);
linkbuf[size-1] = '\0';
free(link);
err = 0;
}
buf_free(&name);
}
buf_free(&buf);
return err;
}
static int sshfs_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
{
int err;
struct buffer buf;
struct buffer handle;
buf_init(&buf, 0);
buf_add_string(&buf, path);
err = sftp_request(SSH_FXP_OPENDIR, &buf, SSH_FXP_HANDLE, &handle);
if (!err) {
int err2;
buf_finish(&handle);
do {
struct buffer name;
err = sftp_request(SSH_FXP_READDIR, &handle, SSH_FXP_NAME, &name);
if (!err) {
if (buf_get_entries(&name, h, filler) == -1)
err = -EPROTO;
buf_free(&name);
}
} while (!err);
if (err == MY_EOF)
err = 0;
err2 = sftp_request(SSH_FXP_CLOSE, &handle, SSH_FXP_STATUS, NULL);
if (!err)
err = err2;
buf_free(&handle);
}
buf_free(&buf);
return err;
}
static int sshfs_mkdir(const char *path, mode_t mode)
{
int err;
struct buffer buf;
buf_init(&buf, 0);
buf_add_string(&buf, path);
buf_add_uint32(&buf, SSH_FILEXFER_ATTR_PERMISSIONS);
buf_add_uint32(&buf, mode);
err = sftp_request(SSH_FXP_MKDIR, &buf, SSH_FXP_STATUS, NULL);
buf_free(&buf);
return err;
}
static int sshfs_mknod(const char *path, mode_t mode, dev_t rdev)
{
int err;
struct buffer buf;
struct buffer handle;
(void) rdev;
if ((mode & S_IFMT) != S_IFREG)
return -EPERM;
buf_init(&buf, 0);
buf_add_string(&buf, path);
buf_add_uint32(&buf, SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_EXCL);
buf_add_uint32(&buf, SSH_FILEXFER_ATTR_PERMISSIONS);
buf_add_uint32(&buf, mode);
err = sftp_request(SSH_FXP_OPEN, &buf, SSH_FXP_HANDLE, &handle);
if (!err) {
int err2;
buf_finish(&handle);
err2 = sftp_request(SSH_FXP_CLOSE, &handle, SSH_FXP_STATUS, NULL);
if (!err)
err = err2;
buf_free(&handle);
}
buf_free(&buf);
return err;
}
static int sshfs_symlink(const char *from, const char *to)
{
int err;
struct buffer buf;
buf_init(&buf, 0);
/* openssh sftp server doesn't follow standard: link target and
link name are mixed up, so we must also be non-standard :( */
buf_add_string(&buf, from);
buf_add_string(&buf, to);
err = sftp_request(SSH_FXP_SYMLINK, &buf, SSH_FXP_STATUS, NULL);
buf_free(&buf);
return err;
}
static int sshfs_unlink(const char *path)
{
int err;
struct buffer buf;
buf_init(&buf, 0);
buf_add_string(&buf, path);
err = sftp_request(SSH_FXP_REMOVE, &buf, SSH_FXP_STATUS, NULL);
buf_free(&buf);
return err;
}
static int sshfs_rmdir(const char *path)
{
int err;
struct buffer buf;
buf_init(&buf, 0);
buf_add_string(&buf, path);
err = sftp_request(SSH_FXP_RMDIR, &buf, SSH_FXP_STATUS, NULL);
buf_free(&buf);
return err;
}
static int sshfs_rename(const char *from, const char *to)
{
int err;
struct buffer buf;
buf_init(&buf, 0);
buf_add_string(&buf, from);
buf_add_string(&buf, to);
err = sftp_request(SSH_FXP_RENAME, &buf, SSH_FXP_STATUS, NULL);
buf_free(&buf);
return err;
}
static int sshfs_chmod(const char *path, mode_t mode)
{
int err;
struct buffer buf;
buf_init(&buf, 0);
buf_add_string(&buf, path);
buf_add_uint32(&buf, SSH_FILEXFER_ATTR_PERMISSIONS);
buf_add_uint32(&buf, mode);
err = sftp_request(SSH_FXP_SETSTAT, &buf, SSH_FXP_STATUS, NULL);
buf_free(&buf);
return err;
}
static int sshfs_chown(const char *path, uid_t uid, gid_t gid)
{
int err;
struct buffer buf;
buf_init(&buf, 0);
buf_add_string(&buf, path);
buf_add_uint32(&buf, SSH_FILEXFER_ATTR_UIDGID);
buf_add_uint32(&buf, uid);
buf_add_uint32(&buf, gid);
err = sftp_request(SSH_FXP_SETSTAT, &buf, SSH_FXP_STATUS, NULL);
buf_free(&buf);
return err;
}
static int sshfs_truncate(const char *path, off_t size)
{
int err;
struct buffer buf;
buf_init(&buf, 0);
buf_add_string(&buf, path);
buf_add_uint32(&buf, SSH_FILEXFER_ATTR_SIZE);
buf_add_uint64(&buf, size);
err = sftp_request(SSH_FXP_SETSTAT, &buf, SSH_FXP_STATUS, NULL);
buf_free(&buf);
return err;
}
static int sshfs_utime(const char *path, struct utimbuf *ubuf)
{
int err;
struct buffer buf;
buf_init(&buf, 0);
buf_add_string(&buf, path);
buf_add_uint32(&buf, SSH_FILEXFER_ATTR_ACMODTIME);
buf_add_uint32(&buf, ubuf->actime);
buf_add_uint32(&buf, ubuf->modtime);
err = sftp_request(SSH_FXP_SETSTAT, &buf, SSH_FXP_STATUS, NULL);
buf_free(&buf);
return err;
}
static int sshfs_open(const char *path, int flags)
{
int err;
struct buffer buf;
struct buffer handle;
uint32_t pflags;
if ((flags & O_ACCMODE) == O_RDONLY)
pflags = SSH_FXF_READ;
else if((flags & O_ACCMODE) == O_WRONLY)
pflags = SSH_FXF_WRITE;
else
pflags = SSH_FXF_READ | SSH_FXF_WRITE;
buf_init(&buf, 0);
buf_add_string(&buf, path);
buf_add_uint32(&buf, pflags);
buf_add_uint32(&buf, 0);
err = sftp_request(SSH_FXP_OPEN, &buf, SSH_FXP_HANDLE, &handle);
if (!err) {
int err2;
buf_finish(&handle);
err2 = sftp_request(SSH_FXP_CLOSE, &handle, SSH_FXP_STATUS, NULL);
if (!err)
err = err2;
buf_free(&handle);
}
buf_free(&buf);
return err;
}
static int sshfs_read(const char *path, char *rbuf, size_t size, off_t offset)
{
int err;
struct buffer buf;
struct buffer handle;
buf_init(&buf, 0);
buf_add_string(&buf, path);
buf_add_uint32(&buf, SSH_FXF_READ);
buf_add_uint32(&buf, 0);
err = sftp_request(SSH_FXP_OPEN, &buf, SSH_FXP_HANDLE, &handle);
if (!err) {
struct buffer data;
int err2;
buf_finish(&handle);
buf_add_uint64(&handle, offset);
buf_add_uint32(&handle, size);
err = sftp_request(SSH_FXP_READ, &handle, SSH_FXP_DATA, &data);
if (!err) {
uint32_t retsize;
err = -EPROTO;
if (buf_get_uint32(&data, &retsize) != -1) {
if (retsize > size)
fprintf(stderr, "long read\n");
else {
buf_get_mem(&data, rbuf, retsize);
err = retsize;
}
}
buf_free(&data);
}
err2 = sftp_request(SSH_FXP_CLOSE, &handle, SSH_FXP_STATUS, NULL);
if (err2 && err >= 0)
err = err2;
buf_free(&handle);
}
buf_free(&buf);
return err;
}
static int sshfs_write(const char *path, const char *wbuf, size_t size,
off_t offset)
{
int err;
struct buffer buf;
struct buffer handle;
buf_init(&buf, 0);
buf_add_string(&buf, path);
buf_add_uint32(&buf, SSH_FXF_WRITE);
buf_add_uint32(&buf, 0);
err = sftp_request(SSH_FXP_OPEN, &buf, SSH_FXP_HANDLE, &handle);
if (!err) {
struct buffer data;
int err2;
data.p = (uint8_t *) wbuf;
data.len = size;
buf_finish(&handle);
buf_add_uint64(&handle, offset);
buf_add_data(&handle, &data);
err = sftp_request(SSH_FXP_WRITE, &handle, SSH_FXP_STATUS, NULL);
err2 = sftp_request(SSH_FXP_CLOSE, &handle, SSH_FXP_STATUS, NULL);
if (err2 && err >= 0)
err = err2;
buf_free(&handle);
}
buf_free(&buf);
return err;
}
static int sftp_init()
{
int res = -1;
uint8_t type;
uint32_t version;
struct buffer buf;
buf_init(&buf, 4);
buf_add_uint32(&buf, PROTO_VERSION);
if (sftp_send(SSH_FXP_INIT, &buf) == -1)
goto out;
buf_clear(&buf);
if (sftp_read(&type, &buf) == -1)
goto out;
if (type != SSH_FXP_VERSION) {
fprintf(stderr, "protocol error\n");
goto out;
}
if (buf_get_uint32(&buf, &version) == -1)
goto out;
if (version != PROTO_VERSION) {
fprintf(stderr, "server version: %i, we need: %i\n",
version, PROTO_VERSION);
goto out;
}
res = 0;
out:
buf_free(&buf);
return res;
}
static struct fuse_operations sshfs_oper = {
.getattr = sshfs_getattr,
.readlink = sshfs_readlink,
.getdir = sshfs_getdir,
.mknod = sshfs_mknod,
.mkdir = sshfs_mkdir,
.symlink = sshfs_symlink,
.unlink = sshfs_unlink,
.rmdir = sshfs_rmdir,
.rename = sshfs_rename,
.chmod = sshfs_chmod,
.chown = sshfs_chown,
.truncate = sshfs_truncate,
.utime = sshfs_utime,
.open = sshfs_open,
.read = sshfs_read,
.write = sshfs_write,
};
int main(int argc, char *argv[])
{
char *host;
int res;
int argctr;
char **newargv;
if (argc < 3) {
fprintf(stderr, "usage: %s [user@]host mountpoint [mount options]\n",
argv[0]);
exit(1);
}
host = argv[1];
res = start_ssh(host);
if (res == -1)
exit(1);
res = sftp_init();
if (res == -1)
exit(1);
newargv = (char **) malloc((argc + 10) * sizeof(char *));
newargv[0] = argv[0];
for (argctr = 1; argctr < argc - 1; argctr++)
newargv[argctr] = argv[argctr + 1];
newargv[argctr++] = "-s";
newargv[argctr++] = "-omax_read=65536";
newargv[argctr] = NULL;
return fuse_main(argctr, newargv, &sshfs_oper);
}