aboutsummaryrefslogtreecommitdiffstats
path: root/plpnfsd
diff options
context:
space:
mode:
authorFritz Elfert <felfert@to.com>2000-10-09 19:14:34 +0000
committerFritz Elfert <felfert@to.com>2000-10-09 19:14:34 +0000
commit55cd25850a312a0b61192ba455908a8bcfe0152b (patch)
treebec49f9270c12b37bd44f6734bcbbfdeec933622 /plpnfsd
parent84bfdac1c9c1d6c82141fbe9f28861a127b9a22b (diff)
downloadplptools-55cd25850a312a0b61192ba455908a8bcfe0152b.tar.gz
plptools-55cd25850a312a0b61192ba455908a8bcfe0152b.tar.bz2
plptools-55cd25850a312a0b61192ba455908a8bcfe0152b.zip
Added process-stuff in procfs.
Added a check for a protocol "psion" in /etc/services
Diffstat (limited to 'plpnfsd')
-rw-r--r--plpnfsd/builtins.h25
-rw-r--r--plpnfsd/main.cc129
-rw-r--r--plpnfsd/mp_pfs_ops.c468
-rw-r--r--plpnfsd/rfsv_api.h1
4 files changed, 532 insertions, 91 deletions
diff --git a/plpnfsd/builtins.h b/plpnfsd/builtins.h
index 64b2823..644f18b 100644
--- a/plpnfsd/builtins.h
+++ b/plpnfsd/builtins.h
@@ -5,7 +5,21 @@
#ifndef _BUILTINS_H_
#define _BUILTINS_H_
+struct builtin_node_t;
+
+typedef struct builtin_child_t {
+ struct builtin_child_t *next;
+ struct builtin_node_t *node;
+} builtin_child;
+
+/**
+ * Support for procfs-like builtin virtual files/directories
+ */
typedef struct builtin_node_t {
+ struct builtin_node_t *next;
+ struct builtin_node_t *parent;
+ builtin_child *childs;
+ char *private_data;
char *name;
unsigned long flags;
long attr;
@@ -14,20 +28,27 @@ typedef struct builtin_node_t {
long (*read)(struct builtin_node_t *node, char *buf, unsigned long offset, long len);
long (*write)(struct builtin_node_t *node, char *buf, unsigned long offset, long len);
long (*sattr)(struct builtin_node_t *node, unsigned long sa, unsigned long da);
+ long (*getlinks)(struct builtin_node_t *node);
+ long (*getdents)(struct builtin_node_t *node, dentry **entries);
} builtin_node;
#define BF_EXISTS_ALWAYS 1
#define BF_NOCACHE 2
+#define BF_ISPROCESS 4
/**
* Register a builtin handler for an entry in /proc
*/
-extern int register_builtin(builtin_node *);
+builtin_node *register_builtin(char *parent, builtin_node *node);
/**
* Deregister a previously registered handler.
*/
-extern int unregister_builtin(char *);
+extern int unregister_builtin(builtin_node *);
+
+extern char *builtin_path(builtin_node *node);
+extern long generic_getlinks(builtin_node *node);
+extern long generic_getdents(builtin_node *node, dentry **entries);
#endif /* _BUILTINS_H_ */
diff --git a/plpnfsd/main.cc b/plpnfsd/main.cc
index ca31a26..da515f5 100644
--- a/plpnfsd/main.cc
+++ b/plpnfsd/main.cc
@@ -80,6 +80,127 @@ long rpcs_ownerSize(builtin_node *) {
return owner.getLen() - 1;
}
+static long psread(builtin_node *node, char *buf, unsigned long offset, long len) {
+ char *s = (char *)node->private_data;
+
+ if (!s)
+ return 0;
+ if (offset >= ((unsigned long)node->size - 1))
+ return 0;
+ s += offset;
+ int sl = node->size - offset;
+ if (sl > len)
+ sl = len;
+ strncpy(buf, s, sl);
+ return sl;
+}
+
+long rpcs_ps() {
+ Enum<rfsv::errs> res;
+ bufferArray psbuf;
+
+ if (!rpcs_isalive())
+ return -1;
+ res = r->queryDrive('C', psbuf);
+ if (res != rfsv::E_PSI_GEN_NONE)
+ return -1;
+ while (!psbuf.empty()) {
+ builtin_node *dn;
+ builtin_node *fn1;
+ builtin_node *fn2;
+ builtin_node *bn;
+ char bname[40];
+
+ bufferStore bs = psbuf.pop();
+ bufferStore bs2 = psbuf.pop();
+ sprintf(bname, "%d", bs.getWord(0));
+
+ dn = (builtin_node *)malloc(sizeof(builtin_node));
+ if (!dn)
+ return -1;
+ fn1 = (builtin_node *)malloc(sizeof(builtin_node));
+ if (!fn1) {
+ free(dn);
+ return -1;
+ }
+ fn2 = (builtin_node *)malloc(sizeof(builtin_node));
+ if (!fn2) {
+ free(fn1);
+ free(dn);
+ return -1;
+ }
+ memset(dn, 0, sizeof(builtin_node));
+ memset(fn1, 0, sizeof(builtin_node));
+ memset(fn2, 0, sizeof(builtin_node));
+
+ /**
+ * Directory, named by the PID
+ */
+ dn->flags = BF_ISPROCESS;
+ dn->name = bname;
+ dn->attr = PSI_A_DIR;
+ dn->getlinks = generic_getlinks;
+ dn->getdents = generic_getdents;
+
+ fn1->name = "cmd";
+ fn1->attr = PSI_A_READ | PSI_A_RDONLY;
+ fn1->private_data = (char *)malloc(strlen(bs.getString(2))+2);
+ if (!fn1->private_data) {
+ free(fn1);
+ free(fn2);
+ free(dn);
+ return -1;
+ }
+ fn1->read = psread;
+ sprintf(fn1->private_data, "%s\n", bs.getString(2));
+ fn1->size = strlen(fn1->private_data);
+
+ fn2->name = "args";
+ fn2->attr = PSI_A_READ | PSI_A_RDONLY;
+ fn2->private_data = (char *)malloc(strlen(bs2.getString())+2);
+ if (!fn2->private_data) {
+ free(fn1->private_data);
+ free(fn1);
+ free(fn2);
+ free(dn);
+ return -1;
+ }
+ fn2->read = psread;
+ sprintf(fn2->private_data, "%s\n", bs2.getString());
+ fn2->size = strlen(fn2->private_data);
+
+ if (!(bn = register_builtin("proc", dn))) {
+ free(fn1->private_data);
+ free(fn1);
+ free(fn2->private_data);
+ free(fn2);
+ free(dn);
+ return -1;
+ }
+ strcpy(bname, builtin_path(bn));
+ if (!register_builtin(bname, fn1)) {
+ free(fn1->private_data);
+ free(fn1);
+ free(fn2->private_data);
+ free(fn2);
+ unregister_builtin(bn);
+ free(dn);
+ return -1;
+ }
+ if (!register_builtin(bname, fn2)) {
+ free(fn2->private_data);
+ free(fn2);
+ unregister_builtin(bn);
+ free(dn);
+ return -1;
+ }
+ free(fn1);
+ free(fn2);
+ free(dn);
+ }
+ return 0;
+}
+
long rfsv_isalive() {
if (!a) {
if (!(a = rf->create(true)))
@@ -343,6 +464,11 @@ int main(int argc, char**argv) {
int verbose = 0;
int status = 0;
+ struct servent *se = getservbyname("psion", "tcp");
+ endservent();
+ if (se != 0L)
+ sockNum = ntohs(se->s_port);
+
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-p") && i + 1 < argc) {
sockNum = atoi(argv[++i]);
@@ -352,12 +478,15 @@ int main(int argc, char**argv) {
user = argv[++i];
} else if (!strcmp(argv[i], "-v")) {
verbose++;
+ } else if (!strcmp(argv[i], "-D")) {
+ debug++;
} else if (!strcmp(argv[i], "-V")) {
cout << "plpnfsd version " << VERSION << endl;
exit(0);
} else
usage();
}
+
signal(SIGPIPE, SIG_IGN);
skt = new ppsocket();
if (!skt->connect(NULL, sockNum)) {
diff --git a/plpnfsd/mp_pfs_ops.c b/plpnfsd/mp_pfs_ops.c
index a222776..35bae4a 100644
--- a/plpnfsd/mp_pfs_ops.c
+++ b/plpnfsd/mp_pfs_ops.c
@@ -128,15 +128,291 @@ static long generic_sattr(builtin_node *p, unsigned long sa, unsigned long da) {
return 0;
}
-static builtin_node builtins[] = {
- { "owner", 0, PSI_A_READ | PSI_A_RDONLY, 0, rpcs_ownerSize, rpcs_ownerRead, NULL, NULL },
- { "debuglevel", BF_EXISTS_ALWAYS|BF_NOCACHE, PSI_A_READ, 0, param_getsize, param_read, param_write, generic_sattr },
- { "acache", BF_EXISTS_ALWAYS|BF_NOCACHE, PSI_A_READ, 0, param_getsize, param_read, param_write, generic_sattr },
- { "dcache", BF_EXISTS_ALWAYS|BF_NOCACHE, PSI_A_READ, 0, param_getsize, param_read, param_write, generic_sattr },
- { "unixowner", BF_EXISTS_ALWAYS|BF_NOCACHE, PSI_A_READ, 0, user_getsize, user_read, user_write, NULL },
- { "exit", BF_EXISTS_ALWAYS|BF_NOCACHE, PSI_A_READ, 5, NULL, exit_read, exit_write, NULL },
+long generic_getlinks(builtin_node *node) {
+ builtin_child *cp = node->childs;
+ long ncount = 0;
+
+ while (cp) {
+ if ((cp->node->flags & BF_EXISTS_ALWAYS) || rfsv_isalive())
+ ncount++;
+ cp = cp->next;
+ }
+ return ncount;
+}
+
+long generic_getdents(builtin_node *node, dentry **e) {
+ builtin_child *cp = node->childs;
+
+ while (cp) {
+ if ((cp->node->flags & BF_EXISTS_ALWAYS) || rfsv_isalive()) {
+ dentry *tmp = (dentry *)malloc(sizeof(dentry));
+ if (!tmp)
+ return -1;
+ tmp->time = time(0);
+ tmp->size = cp->node->getsize ? cp->node->getsize(cp->node) : cp->node->size;
+ tmp->attr = cp->node->attr;
+ tmp->name = strdup(cp->node->name);
+ tmp->next = *e;
+ *e = tmp;
+ }
+ cp = cp->next;
+ }
+ return 0;
+}
+
+static builtin_node *builtins = NULL;
+static void dump_proctree(builtin_node *n);
+
+static void clear_procs(builtin_child **childs) {
+ builtin_child **cp = childs;
+
+ debuglog("Before clear_procs\n");
+ dump_proctree(builtins);
+ while (*cp) {
+ if ((*cp)->node->flags & BF_ISPROCESS) {
+ builtin_child *tmp = *cp;
+ *cp = (*cp)->next;
+ unregister_builtin(tmp->node);
+ free(tmp);
+ } else
+ cp = &((*cp)->next);
+ }
+ debuglog("After clear_procs\n");
+ dump_proctree(builtins);
+}
+
+static time_t procs_stamp = 0;
+static long procs_keep = 10;
+
+static long proc_getlinks(builtin_node *node) {
+ builtin_child *cp;
+ long ncount = 0;
+
+ if ((time(0) - procs_stamp) > procs_keep) {
+ debuglog("PROCESSLIST\n");
+ clear_procs(&node->childs);
+ rpcs_ps();
+ procs_stamp = time(0);
+ debuglog("After rpcs_ps\n");
+ dump_proctree(builtins);
+ }
+ cp = node->childs;
+ while (cp) {
+ if ((cp->node->flags & BF_EXISTS_ALWAYS) || rfsv_isalive())
+ ncount++;
+ cp = cp->next;
+ }
+ return ncount;
+}
+
+static long proc_getdents(builtin_node *node, dentry **e) {
+ builtin_child *cp = node->childs;
+
+ while (cp) {
+ if ((cp->node->flags & BF_EXISTS_ALWAYS) || rfsv_isalive()) {
+ dentry *tmp = (dentry *)malloc(sizeof(dentry));
+ if (!tmp)
+ return -1;
+ tmp->time = time(0);
+ tmp->size = cp->node->getsize ? cp->node->getsize(cp->node) : cp->node->size;
+ tmp->attr = cp->node->attr;
+ tmp->name = strdup(cp->node->name);
+ tmp->next = *e;
+ *e = tmp;
+ }
+ cp = cp->next;
+ }
+ return 0;
+}
+
+
+static builtin_node proc_node = {
+ NULL, NULL, NULL, NULL, "proc", BF_EXISTS_ALWAYS|BF_NOCACHE, PSI_A_DIR, 0, NULL, NULL, NULL, NULL, proc_getlinks, proc_getdents
};
-static int num_builtins = sizeof(builtins) / sizeof(builtin_node);
+
+static builtin_node fixed_builtins[] = {
+ { NULL, NULL, NULL, NULL, "owner", 0, PSI_A_READ | PSI_A_RDONLY, 0, rpcs_ownerSize, rpcs_ownerRead, NULL, NULL, NULL, NULL },
+ { NULL, NULL, NULL, NULL, "debuglevel", BF_EXISTS_ALWAYS|BF_NOCACHE, PSI_A_READ, 0, param_getsize, param_read, param_write, generic_sattr, NULL, NULL },
+ { NULL, NULL, NULL, NULL, "acache", BF_EXISTS_ALWAYS|BF_NOCACHE, PSI_A_READ, 0, param_getsize, param_read, param_write, generic_sattr, NULL, NULL },
+ { NULL, NULL, NULL, NULL, "dcache", BF_EXISTS_ALWAYS|BF_NOCACHE, PSI_A_READ, 0, param_getsize, param_read, param_write, generic_sattr, NULL, NULL },
+ { NULL, NULL, NULL, NULL, "unixowner", BF_EXISTS_ALWAYS|BF_NOCACHE, PSI_A_READ, 0, user_getsize, user_read, user_write, NULL, NULL, NULL },
+ { NULL, NULL, NULL, NULL, "exit", BF_EXISTS_ALWAYS|BF_NOCACHE, PSI_A_READ, 5, NULL, exit_read, exit_write, NULL, NULL, NULL },
+};
+static int num_fixed_builtins = sizeof(fixed_builtins) / sizeof(builtin_node);
+
+static void dump_proctree(builtin_node *n) {
+ while (n) {
+ if (n->name)
+ debuglog("node@%p, \"%s\"\n", n, n->name);
+ else
+ debuglog("node@%p, \"(null)\"\n", n);
+ if (n->childs) {
+ builtin_child *c = n->childs;
+ debuglog("Childs:\n");
+ while (c) {
+ if (c->node)
+ debuglog(" %s\n", c->node->name ? c->node->name : "(null)");
+ c = c->next;
+ }
+ }
+ if (n->parent)
+ debuglog("Parent: %s\n", n->parent->name);
+ n = n->next;
+ }
+}
+
+static int add_child(builtin_child **childs, builtin_node *node) {
+ builtin_child *newc = malloc(sizeof(builtin_child));
+ if (!newc) {
+ errorlog("Out of memory in add_child %s\n", node->name);
+ return -1;
+ }
+ newc->next = *childs;
+ newc->node = node;
+ *childs = newc;
+ return 0;
+}
+
+static int remove_child(builtin_child **childs, builtin_node *node) {
+ builtin_child **cp = childs;
+
+ if (debug)
+ debuglog("remove_child %s\n", node->name);
+ while (*cp) {
+ if ((*cp)->node == node) {
+ builtin_child *tmp = *cp;
+ *cp = (*cp)->next;
+ free(tmp);
+ return 0;
+ }
+ cp = &((*cp)->next);
+ }
+ return -1;
+}
+
+char *builtin_path(builtin_node *node) {
+ static char tmp[1024];
+ char tmp2[1024];
+
+ strcpy(tmp, node->name);
+ node = node->parent;
+ while (node) {
+ sprintf(tmp2, "%s\\%s", node->name, tmp);
+ strcpy(tmp, tmp2);
+ node = node->parent;
+ }
+ return tmp;
+}
+
+int unregister_builtin(builtin_node *node) {
+ builtin_child *cp = node->childs;
+ builtin_node **n;
+
+ /**
+ * Unlink and free childs.
+ */
+ if (debug)
+ debuglog("unregister_builtin %s\n", node->name);
+
+ while (cp) {
+ builtin_child *old = cp;
+ cp->node->parent = 0L;
+ unregister_builtin(cp->node);
+ cp = cp->next;
+ free(old);
+ }
+ /**
+ * Unlink ourselves from parent child list.
+ */
+ if (node->parent)
+ remove_child(&node->parent->childs, node);
+ n = &builtins;
+ while (*n) {
+ if (*n == node) {
+ *n = node->next;
+ break;
+ } else
+ n = &(*n)->next;
+ }
+ if (node->name)
+ free(node->name);
+ if (node->private_data)
+ free(node->private_data);
+ free(node);
+ return 0;
+}
+
+builtin_node *register_builtin(char *parent, builtin_node *node) {
+ builtin_node *bn;
+ builtin_node *parent_node = 0L;
+
+ debuglog("register_builtin node=%p\n", node);
+ if (!node) {
+ errorlog("register_builtin called with NULL node\n");
+ return NULL;
+ }
+ if (!node->name) {
+ errorlog("register_builtin called without name\n");
+ return NULL;
+ }
+ if (parent) {
+ debuglog("register_builtin parent: %s\n", parent);
+ for (bn = builtins; bn; bn = bn->next) {
+ debuglog("cmp parent: %s %s\n", builtin_path(bn), parent);
+ if (!strcmp(builtin_path(bn), parent)) {
+ debuglog("cmp parent found bn=%s\n", bn->name);
+ break;
+ }
+ }
+ if (!bn) {
+ errorlog("register_builtin for %s called with nonexistent parent %s\n", node->name, parent);
+ return NULL;
+ }
+ parent_node = bn;
+ }
+ bn = malloc(sizeof(builtin_node));
+ if (!bn) {
+ errorlog("out of memory while registering builtin %s\n", node->name);
+ return NULL;
+ }
+ memset(bn, 0, sizeof(builtin_node));
+ bn->name = strdup(node->name);
+ if (!bn->name) {
+ errorlog("out of memory while registering builtin %s\n", node->name);
+ free(bn);
+ return NULL;
+ }
+ if (parent_node)
+ debuglog("register_builtin %s in %s\n", node->name, builtin_path(parent_node));
+ else
+ debuglog("register_builtin %s\n", node->name);
+ bn->parent = parent_node;
+ bn->flags = node->flags;
+ bn->attr = node->attr;
+ bn->size = node->size;
+ bn->getsize = node->getsize;
+ bn->read = node->read;
+ bn->write = node->write;
+ bn->sattr = node->sattr;
+ bn->getlinks = node->getlinks;
+ bn->getdents = node->getdents;
+ bn->private_data = node->private_data;
+ if (parent_node) {
+ debuglog("Add child %s in %s\n", bn->name, bn->parent->name);
+ if (add_child(&(parent_node->childs), bn)) {
+ errorlog("Couldn't add child %s\n", bn->name);
+ free(bn->name);
+ free(bn);
+ return NULL;
+ }
+ }
+ bn->next = builtins;
+ builtins = bn;
+ debuglog("After register_builtin\n");
+ dump_proctree(builtins);
+ debuglog("register_builtin new node=%p\n", bn);
+ return bn;
+}
/*
* Nfsd returned NFSERR_STALE if the psion wasn't present, but I didn't like
@@ -308,12 +584,25 @@ pattr2attr(long psiattr, long size, long ftime, fattr *fp, int inode)
fp->mtime.seconds = fp->ctime.seconds = fp->atime.seconds;
}
+static int proc_top = 0;
+
static int
query_devices()
{
device *dp, *np;
int link_count = 2; /* set the root link count */
+ if (!proc_top) {
+ int i;
+ if (register_builtin(NULL, &proc_node)) {
+ for (i = 0; i < num_fixed_builtins; i++)
+ if (register_builtin(proc_node.name, &fixed_builtins[i]))
+ proc_top++;
+ } else
+ errorlog("Couldn't register /proc\n");
+ if (proc_top != num_fixed_builtins)
+ proc_top = 0;
+ }
if (query_cache)
return 0;
for (dp = devices; dp; dp = np) {
@@ -336,15 +625,16 @@ mp_dircount(p_inode *inode, long *count)
{
dentry *e = NULL;
long ret;
+ builtin_node *bn;
*count = 0;
debuglog("dircount: %s\n", inode->name);
- if (!strcmp(inode->name, "proc")) {
- int i;
- for (i = 0; i < num_builtins; i++)
- if ((builtins[i].flags & BF_EXISTS_ALWAYS) || rfsv_isalive())
- (*count)++;
- return 0;
+ for (bn = builtins; bn; bn = bn->next) {
+ if ((!strcmp(builtin_path(bn), inode->name) && (bn->attr & PSI_A_DIR))) {
+ if (bn->getlinks)
+ *count = bn->getlinks(bn);
+ return 0;
+ }
}
debuglog("RFSV dir %s\n", inode->name);
if ((ret = rfsv_dir(dirname(inode->name), &e)))
@@ -391,18 +681,6 @@ nfsproc_getattr_2(struct nfs_fh *fh)
if ((cp = search_cache(attrcache, inode->inode))) {
debuglog("getattr: cache hit\n");
*fp = cp->attr; /* gotcha */
-#if 0
- if (fp->type == NFDIR) {
- if (mp_dircount(inode, &dcount)) {
- res.status = rfsv_isalive() ? NFSERR_NOENT : NO_PSION;
- return &res;
- }
- if (fp->nlink != (dcount + 2))
- fp->mtime.seconds = time(0);
- fp->nlink = dcount + 2;
- cp->attr = *fp;
- }
-#endif
return &res;
}
l = strlen(inode->name);
@@ -414,15 +692,6 @@ nfsproc_getattr_2(struct nfs_fh *fh)
if (query_devices()) /* root inode and proc is always there */
root_fattr.nlink = 3;
*fp = root_fattr;
- } else if (l == 4 && (!strcmp(inode->name, "proc"))) {
- debuglog("getattr:proc (%#o)\n", root_fattr.mode);
- *fp = root_fattr;
- fp->fileid = inode->inode;
- fp->type = NFDIR;
- mp_dircount(inode, &dcount);
- if (fp->nlink != (dcount + 2))
- fp->mtime.seconds = time(0);
- fp->nlink = dcount + 2;
} else if (l == 2 && inode->name[1] == ':') {
debuglog("getattr:device\n");
res.status = NO_PSION;
@@ -453,16 +722,19 @@ nfsproc_getattr_2(struct nfs_fh *fh)
}
}
} else {
- int i;
-
- for (i = 0; i < num_builtins; i++) {
- if (!strcmp(inode->name, build_path("proc", builtins[i].name))) {
- pattr = builtins[i].attr;
- psize = (builtins[i].getsize != NULL) ? builtins[i].getsize(&builtins[i]) : builtins[i].size;
+ builtin_node *bn;
+
+ for (bn = builtins; bn; bn = bn->next) {
+ if (!strcmp(inode->name, builtin_path(bn))) {
+ pattr = bn->attr;
+ if (pattr & PSI_A_DIR)
+ psize = 0;
+ else
+ psize = (bn->getsize) ? bn->getsize(bn) : bn->size;
ptime = time(0);
res.status = NFS_OK;
builtin = 1;
- if (builtins[i].flags && BF_NOCACHE)
+ if (bn->flags && BF_NOCACHE)
builtin++;
break;
}
@@ -621,37 +893,44 @@ nfsproc_readdir_2(readdirargs *ra)
addentry(ra, &cp, &searchinode, get_nam(dp->name)->inode, n);
}
} else {
+ builtin_node *bn;
+ int builtin = 0;
dentry *e = NULL;
debuglog("nfsdir: dir\n");
- if (!strcmp(inode->name, "proc")) {
- int i;
- for (i = 0; i < num_builtins; i++)
- if ((builtins[i].flags & BF_EXISTS_ALWAYS) || rfsv_isalive()) {
- int ni = get_nam(build_path(inode->name, builtins[i].name))->inode;
- addentry(ra, &cp, &searchinode, ni, builtins[i].name);
+
+ for (bn = builtins; bn ; bn = bn->next)
+ if (!strcmp(inode->name, builtin_path(bn))) {
+ if (bn->attr & PSI_A_DIR) {
+ if (bn->getdents)
+ bn->getdents(bn, &e);
+ builtin = 1;
+ } else {
+ res.status = NFSERR_NOTDIR;
+ return &res;
}
- } else {
+ }
+ if (!builtin) {
debuglog("RFSV dir2 %s\n", inode->name);
if (rfsv_dir(dirname(inode->name), &e)) {
res.status = rfsv_isalive() ? NFSERR_NOENT : NO_PSION;
return &res;
}
- while (e) {
- fattr fp;
- dentry *o;
- int ni;
+ }
+ while (e) {
+ fattr fp;
+ dentry *o;
+ int ni;
- bp = filname(e->name);
- ni = get_nam(build_path(inode->name, bp))->inode;
- addentry(ra, &cp, &searchinode, ni, (char *) bp);
- free(e->name);
- pattr2attr(e->attr, e->size, e->time, &fp, ni);
- if (rfsv_isalive())
- add_cache(&attrcache, ni, &fp);
- o = e;
- e = e->next;
- free(o);
- }
+ bp = filname(e->name);
+ ni = get_nam(build_path(inode->name, bp))->inode;
+ addentry(ra, &cp, &searchinode, ni, (char *) bp);
+ free(e->name);
+ pattr2attr(e->attr, e->size, e->time, &fp, ni);
+ if (rfsv_isalive())
+ add_cache(&attrcache, ni, &fp);
+ o = e;
+ e = e->next;
+ free(o);
}
}
@@ -666,7 +945,7 @@ nfsproc_setattr_2(sattrargs *sa)
static struct attrstat res;
p_inode *inode = get_num(fh2inode(sa->file.data));
fattr *fp;
- int bi;
+ builtin_node *bn;
int builtin = 0;
if (!inode) {
@@ -680,19 +959,18 @@ nfsproc_setattr_2(sattrargs *sa)
return &res;
fp = &res.attrstat_u.attributes;
- for (bi = 0; bi < num_builtins; bi++) {
- if (!strcmp(inode->name, build_path("proc", builtins[bi].name))) {
+ for (bn = builtins; bn; bn = bn->next)
+ if (!strcmp(inode->name, builtin_path(bn))) {
builtin = 1;
break;
}
- }
if ((fp->type == NFREG) &&
(sa->attributes.size != -1) &&
(sa->attributes.size != fp->size)) {
debuglog("RFSV setsize %s %d\n", inode->name, sa->attributes.size);
if (builtin) {
- if (builtins[bi].attr & PSI_A_RDONLY) {
+ if (bn->attr & PSI_A_RDONLY) {
res.status = NFSERR_ACCES;
return &res;
}
@@ -726,7 +1004,7 @@ nfsproc_setattr_2(sattrargs *sa)
attr2pattr(sa->attributes.mode, fp->mode, &psisattr, &psidattr);
debuglog("RFSV setattr %s %d %d\n", inode->name, psisattr, psidattr);
if (builtin) {
- if ((builtins[bi].sattr == NULL) || builtins[bi].sattr(&builtins[bi], psisattr, psidattr)) {
+ if ((bn->sattr == NULL) || bn->sattr(bn, psisattr, psidattr)) {
res.status = NFSERR_ACCES;
return &res;
}
@@ -874,7 +1152,7 @@ nfsproc_read_2(struct readargs *ra)
long psize;
long ptime;
int len = 0;
- int bi;
+ builtin_node *bn;
int builtin = 0;
if (!inode) {
@@ -897,12 +1175,19 @@ nfsproc_read_2(struct readargs *ra)
debuglog("RFSV read %s\n", inode->name);
- for (bi = 0; bi < num_builtins; bi++) {
- if (!strcmp(inode->name, build_path("proc", builtins[bi].name))) {
- if (builtins[bi].read != NULL) {
- len = builtins[bi].read(&builtins[bi], rop, ra->offset, ra->count);
+ for (bn = builtins; bn; bn = bn->next) {
+ if (!strcmp(inode->name, builtin_path(bn))) {
+ if (bn->attr & PSI_A_DIR) {
+ res.status = NFSERR_ISDIR;
+ return &res;
+ }
+ if (bn->read) {
+ len = bn->read(bn, rop, ra->offset, ra->count);
builtin = 1;
break;
+ } else {
+ res.status = NFSERR_IO;
+ return &res;
}
}
}
@@ -919,8 +1204,8 @@ nfsproc_read_2(struct readargs *ra)
// Problem: if an epoc process is enlarging the file, we wont recognize it
debuglog("RFSV getattr %s\n", inode->name);
if (builtin) {
- pattr = builtins[bi].attr;
- psize = (builtins[bi].getsize != NULL) ? builtins[bi].getsize(&builtins[bi]) : builtins[bi].size;
+ pattr = bn->attr;
+ psize = (bn->getsize) ? bn->getsize(bn) : bn->size;
ptime = time(0);
} else
rfsv_getattr(inode->name, &pattr, &psize, &ptime);
@@ -1034,7 +1319,8 @@ nfsproc_write_2(writeargs *wa)
fattr *fp;
struct attrstat *gres;
int len = 0;
- int i, dlen, doff;
+ int dlen, doff;
+ builtin_node *bn;
if (!inode) {
debuglog("write: stale fh\n");
@@ -1046,6 +1332,21 @@ nfsproc_write_2(writeargs *wa)
dlen = wa->data.data_len;
doff = wa->offset;
+ for (bn = builtins; bn ; bn = bn->next) {
+ if (!strcmp(inode->name, builtin_path(bn))) {
+ if (bn->attr & PSI_A_DIR)
+ res.status = NFSERR_ISDIR;
+ else {
+ debuglog("builtin write %s %d@%d\n", inode->name, dlen, doff);
+ if (bn->write) {
+ int l = bn->write(bn, (unsigned char *)wa->data.data_val, doff, dlen);
+ res.status = (l == dlen) ? NFS_OK : NFSERR_IO;
+ } else
+ res.status = NFSERR_ACCES;
+ }
+ return &res;
+ }
+ }
/* fetch attributes */
if ((cp = search_cache(attrcache, inode->inode)) == 0) {
gres = nfsproc_getattr_2((struct nfs_fh *) wa->file.data);
@@ -1068,17 +1369,6 @@ nfsproc_write_2(writeargs *wa)
res.attrstat_u.attributes = *fp;
- for (i = 0; i < num_builtins; i++) {
- if (!strcmp(inode->name, build_path("proc", builtins[i].name))) {
- debuglog("builtin write %s %d@%d\n", inode->name, dlen, doff);
- if (builtins[i].write != NULL) {
- int l = builtins[i].write(&builtins[i], (unsigned char *)wa->data.data_val, doff, dlen);
- res.status = (l == dlen) ? NFS_OK : NFSERR_IO;
- } else
- res.status = NFSERR_ACCES;
- return &res;
- }
- }
if (addwritecache(cp, doff, dlen, (unsigned char *) wa->data.data_val)) {
res.status = NFS_OK;
return &res;
diff --git a/plpnfsd/rfsv_api.h b/plpnfsd/rfsv_api.h
index b780735..5a9072e 100644
--- a/plpnfsd/rfsv_api.h
+++ b/plpnfsd/rfsv_api.h
@@ -32,6 +32,7 @@ extern long rfsv_closecached(void);
extern long rpcs_ownerRead(builtin_node *, char *buf, unsigned long offset, long len);
extern long rpcs_ownerSize(builtin_node *);
+extern long rpcs_ps();
/* File attributes, C-style */
#define PSI_A_RDONLY 0x0001