#define FUSE_USE_VERSION 30 #include #include #include #include #include #include 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); }