diff options
Diffstat (limited to 'plpfuse')
-rw-r--r-- | plpfuse/.cvsignore | 5 | ||||
-rw-r--r-- | plpfuse/Makefile.am | 9 | ||||
-rw-r--r-- | plpfuse/fuse.c | 528 | ||||
-rw-r--r-- | plpfuse/main.cc | 380 | ||||
-rw-r--r-- | plpfuse/plpfuse.h | 52 | ||||
-rw-r--r-- | plpfuse/rfsv_api.h | 76 |
6 files changed, 1050 insertions, 0 deletions
diff --git a/plpfuse/.cvsignore b/plpfuse/.cvsignore new file mode 100644 index 0000000..6ccdb58 --- /dev/null +++ b/plpfuse/.cvsignore @@ -0,0 +1,5 @@ +Makefile.in +Makefile +.libs +.deps +plpfuse diff --git a/plpfuse/Makefile.am b/plpfuse/Makefile.am new file mode 100644 index 0000000..467baaf --- /dev/null +++ b/plpfuse/Makefile.am @@ -0,0 +1,9 @@ +# $Id$ +# +INCLUDES=-I$(top_srcdir)/lib + +sbin_PROGRAMS = plpfuse +plpfuse_LDADD = $(LIB_PLP) $(INTLLIBS) -lfuse +plpfuse_SOURCES = main.cc fuse.c + +EXTRA_DIST = rfsv_api.h diff --git a/plpfuse/fuse.c b/plpfuse/fuse.c new file mode 100644 index 0000000..92720e2 --- /dev/null +++ b/plpfuse/fuse.c @@ -0,0 +1,528 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> + Copyright (C) 2007 Reuben Thomas <rrt@sc3d.org> + + This program can be distributed under the terms of the GNU GPL. + See the file COPYING. +*/ + +// FIXME: Map errors sensibly from EPOC to UNIX + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/time.h> +#include <errno.h> +#include <syslog.h> + +#include <fuse.h> +#include "rfsv_api.h" + +#include "plpfuse.h" + +#define NO_PSION ENOMEDIUM + +int debug; + +int +debuglog(char *fmt, ...) +{ + va_list ap; + char *buf; + + //if (!debug) + // return 0; + va_start(ap, fmt); + vasprintf(&buf, fmt, ap); + syslog(LOG_DEBUG, "%s", buf); + free(buf); + va_end(ap); + return 0; +} + +static void +attr2pattr(long oattr, long nattr, long *psisattr, long *psidattr) +{ + /* + * Following flags have to be set in order to let backups + * work properly + */ + *psisattr = *psidattr = 0; + if ((oattr & 0400) != (nattr & 0400)) { + if (nattr & 0400) /* readable */ + *psisattr |= PSI_A_READ; + else + *psidattr |= PSI_A_READ; + } + if ((oattr & 0200) != (nattr & 0200)) { + if (nattr & 0200) /* Not writable -> readonly */ + *psidattr |= PSI_A_RDONLY; + else + *psisattr |= PSI_A_RDONLY; + } + if ((oattr & 0020) != (nattr & 0020)) { + if (nattr & 0020) /* group-write -> archive */ + *psisattr |= PSI_A_ARCHIVE; + else + *psidattr |= PSI_A_ARCHIVE; + } + if ((oattr & 0004) != (nattr & 0004)) { + if (nattr & 0004) /* Not world-read -> hidden */ + *psidattr |= PSI_A_HIDDEN; + else + *psisattr |= PSI_A_HIDDEN; + } + if ((oattr & 0002) != (nattr & 0002)) { + if (nattr & 0002) /* world-write -> system */ + *psisattr |= PSI_A_SYSTEM; + else + *psidattr |= PSI_A_SYSTEM; + } +} + +static void +pattr2attr(long psiattr, long size, long ftime, struct stat *st) +{ + struct fuse_context *ct = fuse_get_context(); + + memset(st, 0, sizeof(*st)); + + st->st_uid = ct->uid; + st->st_gid = ct->gid; + + if (psiattr & PSI_A_DIR) { + st->st_mode = 0700 | S_IFDIR; + st->st_blocks = 1; + st->st_size = BLOCKSIZE; + st->st_nlink = 2; /* Call dircount for more accurate count */ + } else { + st->st_blocks = (size + BLOCKSIZE - 1) / BLOCKSIZE; + st->st_size = size; + st->st_nlink = 1; + st->st_mode = S_IFREG; + + /* + * Following flags have to be set in order to let backups + * work properly + */ + if (psiattr & PSI_A_READ) + st->st_mode |= 0400; /* File readable (?) */ + if (!(psiattr & PSI_A_RDONLY)) + st->st_mode |= 0200; /* File writeable */ + /* st->st_mode |= 0100; File executable */ + if (!(psiattr & PSI_A_HIDDEN)) + st->st_mode |= 0004; /* Not Hidden <-> world read */ + if (psiattr & PSI_A_SYSTEM) + st->st_mode |= 0002; /* System <-> world write */ + if (psiattr & PSI_A_VOLUME) + st->st_mode |= 0001; /* Volume <-> world exec */ + if (psiattr & PSI_A_ARCHIVE) + st->st_mode |= 0020; /* Modified <-> group write */ + /* st->st_mode |= 0040; Byte <-> group read */ + /* st->st_mode |= 0010; Text <-> group exec */ + } + + st->st_mtime = st->st_ctime = st->st_atime = ftime; +} + +static device *devices; + +static int +query_devices() +{ + device *dp, *np; + int link_count = 2; /* set the root link count */ + + for (dp = devices; dp; dp = np) { + np = dp->next; + free(dp->name); + free(dp); + } + devices = NULL; + if (rfsv_drivelist(&link_count, &devices)) + return 1; + return 0; +} + +char * +dirname(const char *dir) +{ + static char *namebuf = NULL; + if (namebuf) + free(namebuf); + asprintf(&namebuf, "%s\\", dir); + return namebuf; +} + +const char * +filname(const char *dir) +{ + char *p; + if ((p = (char *) rindex(dir, '\\'))) + return p + 1; + else + return dir; +} + +static int +dircount(const char *path, long *count) +{ + dentry *e = NULL; + long ret = 0; + + *count = 0; + debuglog("dircount: %s", path); + debuglog("RFSV dir %s", path); + if ((ret = rfsv_dir(dirname(path), &e))) + return ret; + while (e) { + struct stat st; + dentry *o = e; + pattr2attr(e->attr, e->size, e->time, &st); + free(e->name); + e = e->next; + free(o); + if (st.st_nlink > 1) + (*count)++; + } + + debuglog("count %d", *count); + return ret; +} + +static int getlinks(const char *path, struct stat *st) +{ + long dcount; + + if (dircount(path, &dcount)) + return rfsv_isalive() ? -ENOENT : -NO_PSION; + st->st_nlink = dcount + 2; + return 0; +} + +static int plp_getattr(const char *path, struct stat *st) +{ + debuglog("plp_getattr `%s'", ++path); + + if (strcmp(path, "") == 0) { + pattr2attr(PSI_A_DIR, 0, 0, st); + if (!query_devices()) { + device *dp; + + for (dp = devices; dp; dp = dp->next) + st->st_nlink++; + debuglog("root has %d links", st->st_nlink); + } else + return rfsv_isalive() ? -ENOENT : -NO_PSION; + } else { + long pattr, psize, ptime; + + if (strlen(path) == 2 && path[1] == ':') { + debuglog("getattr: device"); + if (!query_devices()) { + device *dp; + + for (dp = devices; dp; dp = dp->next) { + debuglog("cmp '%c', '%c'", dp->letter, + path[0]); + if (dp->letter == path[0]) + break; + } + debuglog("device: %s", dp ? "exists" : "does not exist"); + pattr2attr(PSI_A_DIR, 0, 0, st); + return getlinks(path, st); + } else + return rfsv_isalive() ? -ENOENT : -NO_PSION; + } + + debuglog("getattr: fileordir"); + if (rfsv_getattr(path, &pattr, &psize, &ptime)) + return rfsv_isalive() ? -ENOENT : -NO_PSION; + else { + pattr2attr(pattr, psize, ptime, st); + debuglog(" attrs Psion: %x %d %d, UNIX modes: %o", pattr, psize, ptime, st->st_mode); + if (st->st_nlink > 1) + return getlinks(path, st); + } + } + + debuglog("getattr: return OK"); + return 0; +} + +static int plp_access(const char *path, int mask) +{ + debuglog("plp_access `%s'", ++path); + return 0; +} + +static int plp_readlink(const char *path, char *buf, size_t size) +{ + debuglog("plp_readlink `%s'", ++path); + return -EINVAL; +} + + +static int plp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, + off_t offset, struct fuse_file_info *fi) +{ + device *dp; + int ret; + dentry *e = NULL; + + debuglog("plp_readdir `%s'", ++path); + + (void)offset; + (void)fi; + + if (strcmp(path, "") == 0) { + debuglog("readdir root"); + if (query_devices() == 0) { + for (dp = devices; dp; dp = dp->next) { + dentry *o; + struct stat st; + unsigned char name[3]; + + name[0] = dp->letter; + name[1] = ':'; + name[2] = '\0'; + pattr2attr(dp->attrib, 1, 0, &st); + if (filler(buf, name, &st, 0)) + break; + } + } + } else { + debuglog("RFSV dir `%s'", dirname(path)); + if (rfsv_dir(dirname(path), &e)) + return rfsv_isalive() ? -ENOENT : -NO_PSION; + + debuglog("scanning contents"); + while (e) { + dentry *o; + struct stat st; + const char *name = filname(e->name); + + pattr2attr(e->attr, e->size, e->time, &st); + debuglog(" %s %o %d %d", name, st.st_mode, st.st_size, st.st_mtime); + if (filler(buf, name, &st, 0)) + break; + free(e->name); + o = e; + e = e->next; + free(o); + } + } + + debuglog("readdir OK"); + return 0; +} + +static int plp_mknod(const char *path, mode_t mode, dev_t dev) +{ + u_int32_t phandle; + + debuglog("plp_mknod `%s' %o", ++path, mode); + + if (S_ISREG(mode) && dev == 0) { + if (rfsv_fcreate(0x200, path, &phandle)) + return rfsv_isalive() ? -ENAMETOOLONG : -NO_PSION; + rfsv_fclose(phandle); + } else + return -EINVAL; + + return 0; +} + +static int plp_mkdir(const char *path, mode_t mode) +{ + debuglog("plp_mkdir `%s' %o", ++path, mode); + + if (rfsv_mkdir(path)) + return rfsv_isalive() ? -ENAMETOOLONG : -NO_PSION; + + return 0; +} + +static int plp_unlink(const char *path) +{ + debuglog("plp_unlink `%s'", ++path); + + if (rfsv_remove(path)) + return rfsv_isalive() ? -EACCES : -NO_PSION; + + return 0; +} + +static int plp_rmdir(const char *path) +{ + debuglog("plp_rmdir `%s'", ++path); + + if (rfsv_rmdir(path)) + return rfsv_isalive() ? -EACCES : -NO_PSION; + + return 0; +} + +static int plp_symlink(const char *from, const char *to) +{ + debuglog("plp_symlink `%s' -> `'%s'", ++from, ++to); + return -EPERM; +} + +static int plp_rename(const char *from, const char *to) +{ + debuglog("plp_rename `%s' -> `%s'", ++from, ++to); + + rfsv_remove(to); + if (rfsv_rename(from, to)) + return rfsv_isalive() ? -EACCES : -NO_PSION; + + return 0; +} + +static int plp_link(const char *from, const char *to) +{ + debuglog("plp_link `%s' -> `%s'", ++from, ++to); + return -EPERM; +} + +static int plp_chmod(const char *path, mode_t mode) +{ + long psisattr, psidattr, pattr, psize, ptime; + struct stat st; + + debuglog("plp_chmod `%s'", ++path); + + if (rfsv_getattr(path, &pattr, &psize, &ptime)) + return rfsv_isalive() ? -ENOENT : -NO_PSION; + pattr2attr(pattr, psize, ptime, &st); + attr2pattr(st.st_mode, mode, &psisattr, &psidattr); + debuglog(" UNIX old, new: %o, %o; Psion set, clear: %x, %x", st.st_mode, mode, psisattr, psidattr); + if (rfsv_setattr(path, psisattr, psidattr)) + return rfsv_isalive() ? -EACCES : -NO_PSION; + + debuglog("chmod succeeded"); + return 0; +} + +static int plp_chown(const char *path, uid_t uid, gid_t gid) +{ + debuglog("plp_chown `%s'", ++path); + return -EPERM; +} + +static int plp_truncate(const char *path, off_t size) +{ + debuglog("plp_truncate `%s'", ++path); + + if (rfsv_setsize(path, 0)) + return rfsv_isalive() ? -EPERM : -NO_PSION; + + return 0; +} + +static int plp_utimens(const char *path, const struct timespec ts[2]) +{ + struct timeval tv[2]; + + debuglog("plp_utimens `%s'", ++path); + + if (rfsv_setmtime(path, ts[1].tv_sec)) + return rfsv_isalive() ? -EPERM : -NO_PSION; + + return 0; +} + +static int plp_open(const char *path, struct fuse_file_info *fi) +{ + debuglog("plp_open `%s'", ++path); + (void)fi; + return 0; +} + +static int plp_read(const char *path, char *buf, size_t size, off_t offset, + struct fuse_file_info *fi) +{ + long read; + + (void)fi; + debuglog("plp_read `%s' offset %lld size %ld", ++path, offset, size); + + if ((read = rfsv_read(buf, (long)offset, size, path)) < 0) + return rfsv_isalive() ? -ENOENT : -NO_PSION; + + debuglog("read %ld bytes", read); + return read; +} + +static int plp_write(const char *path, const char *buf, size_t size, + off_t offset, struct fuse_file_info *fi) +{ + long written; + + (void)fi; + debuglog("plp_write `%s' offset %lld size %ld", ++path, offset, size); + if ((written = rfsv_write(buf, offset, size, path)) < 0) + return rfsv_isalive() ? -ENOSPC : -NO_PSION; + + debuglog("wrote %ld bytes", written); + return written; +} + +static int plp_statfs(const char *path, struct statvfs *stbuf) +{ + device *dp; + + debuglog("plp_statfs"); + + stbuf->f_bsize = BLOCKSIZE; + stbuf->f_frsize = BLOCKSIZE; + if (query_devices() == 0) { + for (dp = devices; dp; dp = dp->next) { + stbuf->f_blocks += (dp->total + BLOCKSIZE - 1) / BLOCKSIZE; + stbuf->f_bfree += (dp->free + BLOCKSIZE - 1) / BLOCKSIZE; + } + } + stbuf->f_bavail = stbuf->f_bfree; + + /* Don't have numbers for these */ + stbuf->f_files = 0; + stbuf->f_ffree = stbuf->f_favail = 0; + + stbuf->f_fsid = FID; + stbuf->f_flag = 0; /* don't have mount flags */ + stbuf->f_namemax = 255; /* KDMaxFileNameLen% */ + + return 0; +} + +struct fuse_operations plp_oper = { + .getattr = plp_getattr, + .access = plp_access, + .readlink = plp_readlink, + .readdir = plp_readdir, + .mknod = plp_mknod, + .mkdir = plp_mkdir, + .symlink = plp_symlink, + .unlink = plp_unlink, + .rmdir = plp_rmdir, + .rename = plp_rename, + .link = plp_link, + .chmod = plp_chmod, + .chown = plp_chown, + .truncate = plp_truncate, + .utimens = plp_utimens, + .open = plp_open, + .read = plp_read, + .write = plp_write, + .statfs = plp_statfs, +}; diff --git a/plpfuse/main.cc b/plpfuse/main.cc new file mode 100644 index 0000000..a6743b4 --- /dev/null +++ b/plpfuse/main.cc @@ -0,0 +1,380 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * Copyright (C) 2007 Reuben Thomas <rrt@sc3d.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <rfsv.h> +#include <rpcs.h> +#include <rfsvfactory.h> +#include <rpcsfactory.h> +#include <bufferstore.h> +#include <bufferarray.h> +#include <ppsocket.h> + +#include <iostream> +#include <string> + +#include <stdlib.h> +#include <stdio.h> +#include <signal.h> +#include <unistd.h> + +#include "rfsv_api.h" + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <getopt.h> + +using namespace std; + +static rfsv *a; +static rfsvfactory *rf; + +static rpcs *r; +static rpcsfactory *rp; +static bufferStore owner; + +long rfsv_isalive() { + if (!a) { + if (!(a = rf->create(true))) + return 0; + } + return (a->getStatus() == rfsv::E_PSI_GEN_NONE); +} + +long rfsv_dir(const char *file, dentry **e) { + PlpDir entries; + dentry *tmp; + long ret; + + if (!a) + return -1; + ret = a->dir(file, entries); + + for (int i = 0; i < entries.size(); i++) { + PlpDirent pe = entries[i]; + tmp = *e; + *e = (dentry *)calloc(1, sizeof(dentry)); + if (!*e) + return -1; + (*e)->time = pe.getPsiTime().getTime(); + (*e)->size = pe.getSize(); + (*e)->attr = pe.getAttr(); + (*e)->name = strdup(pe.getName()); + (*e)->next = tmp; + } + return ret; +} + +long rfsv_dircount(const char *file, u_int32_t *count) { + if (!a) + return -1; + return a->dircount(file, *count); +} + +long rfsv_rmdir(const char *name) { + if (!a) + return -1; + return a->rmdir(name); +} + +long rfsv_mkdir(const char *file) { + if (!a) + return -1; + return a->mkdir(file); +} + +long rfsv_remove(const char *file) { + if (!a) + return -1; + return a->remove(file); +} + +long rfsv_fclose(long handle) { + if (!a) + return -1; + return a->fclose(handle); +} + +long rfsv_fcreate(long attr, const char *file, u_int32_t *handle) { + u_int32_t ph; + long ret; + + if (!a) + return -1; + ret = a->fcreatefile(attr, file, ph); + *handle = ph; + return ret; +} + +long rfsv_open(const char *name, long mode, u_int32_t *handle) { + long ret, retry; + + if (!a) + return -1; + if (mode == O_RDONLY) + mode = rfsv::PSI_O_RDONLY; + else + mode = rfsv::PSI_O_RDWR; + for (retry = 100; retry > 0 && (ret = a->fopen(a->opMode(mode), name, *handle)) != rfsv::E_PSI_GEN_NONE; retry--) + usleep(20000); + return ret; +} + +long rfsv_read(char *buf, long offset, long len, const char *name) { + u_int32_t ret = 0, r_offset, handle; + + if (!a) + return -1; + if ((ret = rfsv_open(name, O_RDONLY, &handle))) + return ret; + if (a->fseek(handle, offset, rfsv::PSI_SEEK_SET, r_offset) != rfsv::E_PSI_GEN_NONE || + offset != r_offset || + a->fread(handle, (unsigned char *)buf, len, ret) != rfsv::E_PSI_GEN_NONE) + ret = -1; + rfsv_fclose(handle); + return ret; +} + +long rfsv_write(const char *buf, long offset, long len, const char *name) { + u_int32_t ret = 0, r_offset, handle; + + if (!a) + return -1; + if ((ret = rfsv_open(name, O_RDWR, &handle))) + return ret; + if (a->fseek(handle, offset, rfsv::PSI_SEEK_SET, r_offset) != rfsv::E_PSI_GEN_NONE || + offset != r_offset || + a->fwrite(handle, (unsigned char *)buf, len, ret) != rfsv::E_PSI_GEN_NONE) + ret = -1; + rfsv_fclose(handle); + return ret; +} + +long rfsv_setmtime(const char *name, long time) { + if (!a) + return -1; + return a->fsetmtime(name, PsiTime(time)); +} + +long rfsv_setsize(const char *name, long size) { + u_int32_t ph; + long ret; + + if (!a) + return -1; + ret = a->fopen(a->opMode(rfsv::PSI_O_RDWR), name, ph); + if (!ret) { + ret = a->fsetsize(ph, size); + a->fclose(ph); + } + return ret; +} + +long rfsv_setattr(const char *name, long sattr, long dattr) { + if (!a) + return -1; + return a->fsetattr(name, sattr, dattr); +} + +long rfsv_getattr(const char *name, long *attr, long *size, long *time) { + long res; + PlpDirent e; + + if (!a) + return -1; + res = a->fgeteattr(name, e); + *attr = e.getAttr(); + *size = e.getSize(); + *time = e.getPsiTime().getTime(); + return res; +} + +long rfsv_statdev(char letter) { + PlpDrive drive; + + if (!a) + return -1; + return (a->devinfo(letter, drive) != rfsv::E_PSI_GEN_NONE); +} + +long rfsv_rename(const char *oldname, const char *newname) { + if (!a) + return -1; + return a->rename(oldname, newname); +} + +long rfsv_drivelist(int *cnt, device **dlist) { + *dlist = NULL; + u_int32_t devbits; + long ret; + int i; + + if (!a) + return -1; + ret = a->devlist(devbits); + if (ret == 0) + for (i = 0; i < 26; i++) { + PlpDrive drive; + + if ((devbits & 1) && + ((a->devinfo(i + 'A', drive) == rfsv::E_PSI_GEN_NONE))) { + + device *next = *dlist; + *dlist = (device *)malloc(sizeof(device)); + (*dlist)->next = next; + (*dlist)->name = strdup(drive.getName().c_str()); + (*dlist)->total = drive.getSize(); + (*dlist)->free = drive.getSpace(); + (*dlist)->letter = 'A' + i; + (*dlist)->attrib = drive.getMediaType(); + (*cnt)++; + } + devbits >>= 1; + } + return ret; +} + +static void +help() +{ + cerr << _( + "Usage: plpfuse [OPTION...] MOUNTPOINT\n" + "\n" + "Supported options:\n" + "\n" + " -u, --user=USER Specify USER who owns mounted dir\n" + " -d, --debug Increase debugging\n" + " -h, --help Display this text\n" + " -V, --version Print version and exit\n" + " -p, --port=[HOST:]PORT Connect to port PORT on host HOST\n" + " Default for HOST is 127.0.0.1\n" + " Default for PORT is " + ) << DPORT << "\n\n"; +} + +static void +usage() { + cerr << _("Try `plpfuse --help' for more information") << endl; +} + +static struct option opts[] = { + {"help", no_argument, 0, 'h'}, + {"debug", no_argument, 0, 'd'}, + {"version", no_argument, 0, 'V'}, + {"port", required_argument, 0, 'p'}, + {"user", required_argument, 0, 'u'}, + {NULL, 0, 0, 0 } +}; + +static void +parse_destination(const char *arg, const char **host, int *port) +{ + if (!arg) + return; + // We don't want to modify argv, therefore copy it first ... + char *argcpy = strdup(arg); + char *pp = strchr(argcpy, ':'); + + if (pp) { + // host.domain:400 + // 10.0.0.1:400 + *pp ++= '\0'; + *host = argcpy; + } else { + // 400 + // host.domain + // host + // 10.0.0.1 + if (strchr(argcpy, '.') || !isdigit(argcpy[0])) { + *host = argcpy; + pp = 0L; + } else + pp = argcpy; + } + if (pp) + *port = atoi(pp); +} + +int main(int argc, char**argv) { + ppsocket *skt; + ppsocket *skt2; + const char *host = "127.0.0.1"; + int sockNum = DPORT; + int status = 0; + int i, c; + + struct servent *se = getservbyname("psion", "tcp"); + endservent(); + if (se != 0L) + sockNum = ntohs(se->s_port); + +// while ((c = getopt_long(argc, argv, "hVp:d", opts, NULL)) != -1) { +// switch (c) { +// case 'V': +// cerr << _("plpfuse version ") << VERSION << endl; +// return 0; +// case 'h': +// help(); +// break; +// case 'd': +// debug++; +// break; +// case 'p': +// parse_destination(optarg, &host, &sockNum); +// break; +// } +// } + + skt = new ppsocket(); + if (!skt->connect(host, sockNum)) { + cerr << "plpfuse: could not connect to ncpd" << endl; + status = 1; + } + skt2 = new ppsocket(); + if (!skt2->connect(host, sockNum)) { + cerr << "plpfuse: could not connect to ncpd" << endl; + status = 1; + } + if (status == 0) { + rf = new rfsvfactory(skt); + rp = new rpcsfactory(skt2); + a = rf->create(true); + r = rp->create(true); + if (a != NULL && r != NULL) + debuglog("plpfuse: connected, status is %d", status); + else + debuglog("plpfuse: could not create rfsv or rpcs object, connect delayed"); +// for (i = 0; i < optind; i++) +// argv[i + 1] = argv[i + optind]; +// argc -= optind - 1; + status = fuse_main(argc, argv, &plp_oper, NULL); + delete a; + delete r; + } + exit(status); +} diff --git a/plpfuse/plpfuse.h b/plpfuse/plpfuse.h new file mode 100644 index 0000000..c36d717 --- /dev/null +++ b/plpfuse/plpfuse.h @@ -0,0 +1,52 @@ +/* $Id$ + * + */ + +#ifndef _plpfuse_h_ +#define _plpfuse_h_ + +#include <fuse.h> + +typedef struct p_inode { + int inode; + char *name; + struct p_inode *nextnam, *nextnum; +} p_inode; + +/** + * Description of a Psion-Device + */ +typedef struct p_device { + char *name; /* Volume-Name */ + char letter; /* Drive-Letter */ + long attrib; /* Device-Attribs */ + long total; /* Total capacity in bytes */ + long free; /* Free space in bytes */ + struct p_device *next; +} device; + +/* + * Description of a Psion-File/Dir + */ +typedef struct p_dentry +{ + char *name; + long time; + long attr; + long size; + long links; + struct p_dentry *next; +} dentry; + +extern int debug; + +extern int debuglog(char *fmt, ...); +extern int errorlog(char *fmt, ...); +extern int infolog(char *fmt, ...); + +#define BLOCKSIZE 512 +#define FID 7 /* File system id */ + +#endif + +extern struct fuse_operations plp_oper; diff --git a/plpfuse/rfsv_api.h b/plpfuse/rfsv_api.h new file mode 100644 index 0000000..0fe4793 --- /dev/null +++ b/plpfuse/rfsv_api.h @@ -0,0 +1,76 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _rfsv_api_h_ +#define _rfsv_api_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plpfuse.h" + +extern long rfsv_dir(const char *name, dentry **e); +extern long rfsv_mkdir(const char *name); +extern long rfsv_rmdir(const char *name); +extern long rfsv_remove(const char *name); +extern long rfsv_rename(const char *oldname, const char *newname); +extern long rfsv_open(const char *name, long mode, u_int32_t *handle); +extern long rfsv_fclose(long handle); +extern long rfsv_fcreate(long attr, const char *name, u_int32_t *handle); +extern long rfsv_read(char *buf, long offset, long len, const char *name); +extern long rfsv_write(const char *buf, long offset, long len, const char *name); +extern long rfsv_getattr(const char *name, long *attr, long *size, long *time); +extern long rfsv_setattr(const char *name, long sattr, long dattr); +extern long rfsv_setsize(const char *name, long size); +extern long rfsv_setmtime(const char *name, long time); +extern long rfsv_drivelist(int *cnt, device **devlist); +extern long rfsv_dircount(const char *name, long *count); +extern long rfsv_statdev(char letter); +extern long rfsv_isalive(); + +/* File attributes, C-style */ +#define PSI_A_RDONLY 0x0001 +#define PSI_A_HIDDEN 0x0002 +#define PSI_A_SYSTEM 0x0004 +#define PSI_A_DIR 0x0008 +#define PSI_A_ARCHIVE 0x0010 +#define PSI_A_VOLUME 0x0020 +#define PSI_A_NORMAL 0x0040 +#define PSI_A_TEMP 0x0080 +#define PSI_A_COMPRESSED 0x0100 +#define PSI_A_READ 0x0200 +#define PSI_A_EXEC 0x0400 +#define PSI_A_STREAM 0x0800 +#define PSI_A_TEXT 0x1000 + +#ifdef __cplusplus +} +#endif + +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ |