summaryrefslogtreecommitdiff
path: root/dircat.c
diff options
context:
space:
mode:
authorJeremie Koenig <jk@jk.fr.eu.org>2010-08-18 20:44:54 +0000
committerJeremie Koenig <jk@jk.fr.eu.org>2010-08-30 14:14:49 +0200
commitf89f2ccd6f4dde2dc6c6ffabd0f784ecf2a46617 (patch)
treed91af49685bf319a8a38d8d5e2963f4b34542091 /dircat.c
parent85feec46e7d8884a9a34276c7cad8133c5fbb02e (diff)
Fuse the proclist into the root node
* dircat.c, dircat.h: New files, merge directories. * Makefile: Add the dircat module. * main.c: Use dircat to merge the proclist into the root directory, instead of having it as a stand-alone one. * procfs.h, procfs.c: Add a "refresh hack" to have the contents of the root directory recreated on each request. * proclist.c (proclist_make_node): Enable the hack in question.
Diffstat (limited to 'dircat.c')
-rw-r--r--dircat.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/dircat.c b/dircat.c
new file mode 100644
index 00000000..857ba72b
--- /dev/null
+++ b/dircat.c
@@ -0,0 +1,99 @@
+#include <stdlib.h>
+#include <string.h>
+#include "procfs.h"
+
+struct dircat_node
+{
+ struct node **dirs;
+};
+
+static error_t
+dircat_get_contents (void *hook, void **contents, size_t *contents_len)
+{
+ struct dircat_node *dcn = hook;
+ int i, sz, pos;
+ error_t err;
+
+ pos = 0;
+ *contents = malloc (sz = 512);
+
+ for (i=0; dcn->dirs[i]; i++)
+ {
+ void *subcon;
+ size_t sublen;
+
+ err = procfs_get_contents (dcn->dirs[i], &subcon, &sublen);
+ if (err)
+ {
+ free (*contents);
+ *contents = NULL;
+ return err;
+ }
+
+ while (pos + sublen > sz)
+ *contents = realloc (*contents, sz *= 2);
+
+ memcpy (*contents + pos, subcon, sublen);
+ pos += sublen;
+ }
+
+ *contents_len = pos;
+ return 0;
+}
+
+static error_t
+dircat_lookup (void *hook, const char *name, struct node **np)
+{
+ struct dircat_node *dcn = hook;
+ error_t err;
+ int i;
+
+ err = ENOENT;
+ for (i=0; err && dcn->dirs[i]; i++)
+ err = procfs_lookup (dcn->dirs[i], name, np);
+
+ return err;
+}
+
+static void
+dircat_release_dirs (struct node **dirs)
+{
+ int i;
+
+ for (i=0; dirs[i]; i++)
+ netfs_nrele (dirs[i]);
+}
+
+static void
+dircat_cleanup (void *hook)
+{
+ struct dircat_node *dcn = hook;
+
+ dircat_release_dirs (dcn->dirs);
+ free (dcn);
+}
+
+struct node *
+dircat_make_node (struct node **dirs)
+{
+ static struct procfs_node_ops ops = {
+ .get_contents = dircat_get_contents,
+ .cleanup_contents = procfs_cleanup_contents_with_free,
+ .lookup = dircat_lookup,
+ .cleanup = dircat_cleanup,
+ /* necessary so that it propagates to proclist */
+ .enable_refresh_hack_and_break_readdir = 1,
+ };
+ struct dircat_node *dcn;
+
+ dcn = malloc (sizeof *dcn);
+ if (! dcn)
+ {
+ dircat_release_dirs (dirs);
+ return NULL;
+ }
+
+ dcn->dirs = dirs;
+ return procfs_make_node (&ops, dcn);
+}
+