Now we have the fuse-procfs between the calling process and /proc,
let's provide a framework to filter out the files/directories we
don't want to show.

Signed-off-by: Daniel Lezcano <daniel.lezcano@free.fr>
---
 procfs.c |   63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 60 insertions(+), 3 deletions(-)

Index: lxcfs/procfs.c
===================================================================
--- lxcfs.orig/procfs.c
+++ lxcfs/procfs.c
@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <search.h>
 #include <libgen.h>
 #include <errno.h>
 #include <dirent.h>
@@ -21,6 +22,7 @@ enum {
 struct procfs_info {
 	DIR *procdir;
 	DIR *subdir;
+	struct hsearch_data shadow_hash;
 };
 
 struct proxy_file {
@@ -34,6 +36,24 @@ struct procfs_file {
 	} file;
 };
 
+static ENTRY shadow_entries[] = {
+	{ "sys", NULL },
+};
+
+#define ARRAY_SIZE(t) (sizeof(t) / sizeof(t[0]))
+#define SHADOW_HASH_SIZE 32
+
+ENTRY *hash_find(char *key, struct hsearch_data *hash)
+{
+	ENTRY entry, *pentry;
+
+	entry.key = key;
+
+	hsearch_r(entry, FIND, &pentry, hash);
+
+	return pentry;
+}
+
 static int procfs_readlink(const char *path, char *buf, size_t bufsiz)
 {
 	struct fuse_context *context = fuse_get_context();
@@ -78,6 +98,9 @@ static int procfs_open(const char *path,
 	if (strcmp(path, "/"))
 		bname += 1;
 
+ 	if (hash_find(bname, &fsinfo->shadow_hash))
+ 		return -ENOENT;
+
 	pfile = malloc(sizeof(*pfile));
 	if (!pfile)
 		return -ENOMEM;
@@ -149,7 +172,7 @@ static int procfs_opendir(const char *pa
 {
 	struct fuse_context *context = fuse_get_context();
 	struct procfs_info *fsinfo = context->private_data;
-	char *bname = strchr(path, '/');
+	char *bname;
 	int fd;
 
 	if (!strcmp(path, "/")) {
@@ -157,7 +180,12 @@ static int procfs_opendir(const char *pa
 		return 0;
 	}
 
-	fd = openat(dirfd(fsinfo->procdir), bname + 1, O_DIRECTORY);
+	bname = strchr(path, '/') + 1;
+
+	if (hash_find(bname, &fsinfo->shadow_hash))
+		return -ENOENT;
+
+	fd = openat(dirfd(fsinfo->procdir), bname, O_DIRECTORY);
 	if (fd < 0)
 		return -errno;
 
@@ -176,9 +204,14 @@ static int procfs_readdir(const char *pa
 	if (!offset)
 		rewinddir(fsinfo->subdir);
 
-        while (!readdir_r(fsinfo->subdir, &dirent, &direntp) && direntp)
+        while (!readdir_r(fsinfo->subdir, &dirent, &direntp) && direntp) {
+
+		if (hash_find(direntp->d_name, &fsinfo->shadow_hash))
+			continue;
+
 		if (filler(buf, direntp->d_name, NULL, offset++))
 			break;
+	}
 
 	return 0;
 }
@@ -196,6 +229,24 @@ static int procfs_releasedir(const char 
 	return 0;
 }
 
+static int procfs_init_hash(struct hsearch_data *hash, size_t hash_size,
+			    ENTRY entries[], size_t entries_size)
+{
+	int i;
+	ENTRY *pentry;
+
+	memset(hash, 0, sizeof(*hash));
+
+	if (!hcreate_r(hash_size, hash))
+		return -1;
+
+	for (i = 0; i < entries_size; i++)
+		if (!hsearch_r(entries[i], ENTER, &pentry, hash))
+			return -1;
+
+	return 0;
+}
+
 static void *procfs_init(struct fuse_conn_info *conn)
 {
 	struct procfs_info *fsinfo;
@@ -209,6 +260,11 @@ static void *procfs_init(struct fuse_con
 		goto out_free_fsinfo;
 
 	fsinfo->subdir = NULL;
+
+	if (procfs_init_hash(&fsinfo->shadow_hash, SHADOW_HASH_SIZE,
+			     shadow_entries, ARRAY_SIZE(shadow_entries)))
+		goto out_free_fsinfo;
+
 out:
 	return fsinfo;
 
@@ -223,6 +279,7 @@ static void procfs_destroy(void *private
 	struct procfs_info *fsinfo = private_data;
 
 	closedir(fsinfo->procdir);
+	hdestroy_r(&fsinfo->shadow_hash);
 	free(fsinfo);
 }
 



