summaryrefslogtreecommitdiff
path: root/src/usersfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/usersfs.c')
-rw-r--r--src/usersfs.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/usersfs.c b/src/usersfs.c
new file mode 100644
index 0000000..52b9f05
--- /dev/null
+++ b/src/usersfs.c
@@ -0,0 +1,87 @@
+#define FUSE_USE_VERSION 30
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <pwd.h>
+
+#include <fuse.h>
+
+static void * usersfs_init(struct fuse_conn_info *conn)
+{
+
+}
+
+static void usersfs_destroy(void *user_data)
+{
+
+}
+
+static int usersfs_getattr(const char *path, struct stat *stbuf)
+{
+ if (strcmp(path, "/") == 0) {
+ stbuf->st_mode = S_IFDIR | 0755;
+ stbuf->st_nlink = 2;
+ } else {
+ struct passwd *pwent = getpwnam(path + 1);
+ if (pwent && pwent->pw_dir) {
+ stbuf->st_mode = S_IFLNK | 0444;
+ stbuf->st_nlink = 1;
+ } else {
+ return -ENOENT;
+ }
+ }
+ return 0;
+}
+
+static int usersfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
+ off_t offset, struct fuse_file_info *fi)
+{
+ if (strcmp(path, "/") != 0) {
+ return -ENOENT;
+ }
+
+ (void) offset;
+ (void) fi;
+
+ filler(buf, ".", NULL, 0);
+ filler(buf, "..", NULL, 0);
+
+ struct passwd *pwent;
+ setpwent();
+ while (pwent = getpwent()) {
+ if ((pwent->pw_uid == 0 || pwent->pw_uid >= 1000) && pwent->pw_name && pwent->pw_dir) {
+ filler(buf, pwent->pw_name, NULL, 0);
+ }
+ }
+ setpwent();
+
+}
+
+static int usersfs_readlink(const char *path, char *buf, size_t size)
+{
+ if (strcmp(path, "/") == 0) {
+ return -EINVAL;
+ }
+
+ struct passwd *pwent = getpwnam(path + 1);
+ if (pwent && pwent->pw_dir) {
+ strcpy(buf, pwent->pw_dir);
+ return 0;
+ } else {
+ return -ENOENT;
+ }
+}
+
+static struct fuse_operations usersfs_oper = {
+ .getattr = usersfs_getattr,
+ .readdir = usersfs_readdir,
+ .readlink = usersfs_readlink
+};
+
+int main(int argc, char *argv[])
+{
+ return fuse_main(argc, argv, &usersfs_oper, NULL);
+}