diff options
Diffstat (limited to 'plpnfsd/main.cc')
-rw-r--r-- | plpnfsd/main.cc | 163 |
1 files changed, 143 insertions, 20 deletions
diff --git a/plpnfsd/main.cc b/plpnfsd/main.cc index 77f178a..206d902 100644 --- a/plpnfsd/main.cc +++ b/plpnfsd/main.cc @@ -8,10 +8,12 @@ #include <stdlib.h> #include <stdio.h> #include <signal.h> +#include <syslog.h> #include "defs.h" #include "bool.h" -#include "rfsv32.h" +#include "rfsv.h" +#include "rfsvfactory.h" #include "bufferstore.h" #include "bufferarray.h" #include "ppsocket.h" @@ -19,16 +21,30 @@ extern "C" { #include "rfsv_api.h" } -static rfsv32 *a; +static rfsv *a; +static rfsvfactory *rf; +static char *a_filename; +static long a_handle; +static long a_offset; +static long a_openmode; long rfsv_isalive() { - return (a->getStatus() == 0); + if (!a) { + a = rf->create(true); + if (a != NULL) + return (a->getStatus() == 0); + } + return 0; } long rfsv_dir(const char *file, dentry **e) { bufferArray entries; dentry *tmp; - long ret = a->dir(&(*file), &entries); + long ret; + + if (!a) + return -1; + ret = a->dir(&(*file), &entries); while (!entries.empty()) { bufferStore s; s = entries.popBuffer(); @@ -46,10 +62,14 @@ long rfsv_dir(const char *file, dentry **e) { } long rfsv_dircount(const char *file, long *count) { + if (!a) + return -1; return a->dircount(&(*file), &(*count)); } long rfsv_rmdir(const char *name) { + if (!a) + return -1; return a->rmdir(name); } @@ -60,48 +80,129 @@ long rfsv_mkdir(const char *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_fopen(long attr, const char *file, long *handle) { long ph; - long ret = a->fopen(attr, file, ph); + long ret; + + if (!a) + return -1; + ret = a->fopen(a->opMode(attr), file, ph); *handle = ph; return ret; } long rfsv_fcreate(long attr, const char *file, long *handle) { long ph; - long ret = a->fcreatefile(attr, file, ph); + long ret; + + if (!a) + return -1; + ret = a->fcreatefile(attr, file, ph); *handle = ph; return ret; } -long rfsv_read(char *buf, long offset, long len, long handle) { - long ret = a->fseek(handle, offset, rfsv32::PSI_SEEK_SET); - if (ret >= 0) - ret = a->fread(handle, buf, len); +static long rfsv_opencached(const char *name, long mode) { + long ret; + int retry = 100; + + if (!a) + return -1; + while (((ret = a->fopen(a->opMode(mode), name, a_handle)) + == rfsv::E_PSI_GEN_INUSE) && retry--) + ; + if (ret) + return ret; + a_offset = 0; + a_openmode = mode; + a_filename = strdup(name); return ret; } -long rfsv_write(char *buf, long offset, long len, long handle) { - long ret = a->fseek(handle, offset, rfsv32::PSI_SEEK_SET); - if (ret >= 0) - ret = a->fwrite(handle, buf, len); +static long rfsv_closecached() { + if (!a) + return -1; + if (!a_filename) + return 0; + a->fclose(a_handle); + free(a_filename); + a_filename = 0; + return 0; +} + +long rfsv_read(char *buf, long offset, long len, char *name) { + // FIXME: this might break on RFSV16? + long ret = 0; + + if (!a) + return -1; + if (!a_filename || strcmp(a_filename, name) || a_openmode != rfsv::PSI_O_RDONLY) { + rfsv_closecached(); + if((ret = rfsv_opencached(name, rfsv::PSI_O_RDONLY))) + return ret; + } + if (a_offset != offset) + ret = a->fseek(a_handle, offset, rfsv::PSI_SEEK_SET); + if (ret >= 0) { + a_offset = offset; + ret = a->fread(a_handle, (unsigned char *)buf, len); + if (ret <= 0) + return ret; + a_offset += ret; + } + return ret; +} + +long rfsv_write(char *buf, long offset, long len, char *name) { + // FIXME: this might break on RFSV16? + long ret = 0; + + if (!a) + return -1; + + if (!a_filename || strcmp(a_filename, name) || a_openmode != rfsv::PSI_O_RDWR) { + if ((ret = rfsv_closecached())) + return ret; + if ((ret = rfsv_opencached(name, rfsv::PSI_O_RDWR))) + return ret; + } + if (a_offset != offset) + ret = a->fseek(a_handle, offset, rfsv::PSI_SEEK_SET); + if (ret >= 0) { + a_offset = offset; + ret = a->fwrite(a_handle, (unsigned char *)buf, len); + if (ret <= 0) + return ret; + a_offset += ret; + } return ret; } long rfsv_setmtime(const char *name, long time) { + if (!a) + return -1; return a->fsetmtime(name, time); } long rfsv_setsize(const char *name, long size) { long ph; - long ret = a->fopen(rfsv32::PSI_OMODE_READ_WRITE, name, ph); + long ret; + // FIXME: this might break on RFSV16? + + 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); @@ -110,10 +211,14 @@ long rfsv_setsize(const char *name, long size) { } long rfsv_setattr(const char *name, long sattr, long dattr) { + if (!a) + return -1; return a->fsetattr(name, dattr, sattr); } long rfsv_getattr(const char *name, long *attr, long *size, long *time) { + if (!a) + return -1; return a->fgeteattr(&(*name), &(*attr), &(*size), &(*time)); } @@ -122,11 +227,15 @@ long rfsv_statdev(char letter) { int devnum = letter - 'A'; char *name; - name = a->devinfo(devnum, &vfree, &vtotal, &vattr, &vuniqueid); + if (!a) + return -1; + name = a->devinfo(devnum, &vfree, &vtotal, &vattr, &vuniqueid); return (name == NULL); } long rfsv_rename(const char *oldname, const char *newname) { + if (!a) + return -1; return a->rename(oldname, newname); } @@ -136,6 +245,8 @@ long rfsv_drivelist(int *cnt, device **dlist) { long ret; int i; + if (!a) + return -1; ret = a->devlist(&devbits); if (ret == 0) for (i = 0; i<26; i++) { @@ -171,6 +282,7 @@ int main(int argc, char**argv) { char *mdir = DDIR; int sockNum = DPORT; int verbose = 0; + int status = 0; for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "-p") && i + 1 < argc) { @@ -187,10 +299,21 @@ int main(int argc, char**argv) { } else usage(); } - signal(SIGPIPE, SIG_IGN); skt = new ppsocket(); - skt->connect(NULL, sockNum); - a = new rfsv32(skt); - return mp_main(verbose, mdir, user); + if (!skt->connect(NULL, sockNum)) { + cerr << "plpnfsd: could not connect to ncpd" << endl; + status = 1; + } else { + rf = new rfsvfactory(skt); + a = rf->create(true); + openlog("plpnfsd", LOG_PID|LOG_CONS, LOG_DAEMON); + if (a != NULL) + syslog(LOG_INFO, "connected, status is %d", status); + else + syslog(LOG_INFO, "could not create rfsv object, connect delayed"); + status = mp_main(verbose, mdir, user); + delete a; + } + exit(status); } |