diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2001-10-28 19:44:14 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2001-10-28 19:44:14 +0000 |
commit | 85c74fcdfd9e67d411c3e1734b34effd0d73fa4d (patch) | |
tree | 908e39d3e0b84bd733261cdde16ef6ae707f2352 /lib/mount.c | |
parent | 90d8bef61c8c40472ddfb1aafeeb6473ec51a053 (diff) | |
download | libfuse-85c74fcdfd9e67d411c3e1734b34effd0d73fa4d.tar.gz |
x
Diffstat (limited to 'lib/mount.c')
-rw-r--r-- | lib/mount.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/lib/mount.c b/lib/mount.c new file mode 100644 index 0000000..ace3c65 --- /dev/null +++ b/lib/mount.c @@ -0,0 +1,142 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2001 Miklos Szeredi (mszeredi@inf.bme.hu) + + This program can be distributed under the terms of the GNU GPL. + See the file COPYING. +*/ + +#include "fuse_i.h" +#include <linux/fuse.h> + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <sys/mount.h> +#include <mntent.h> + +static int do_mount(const char *dev, const char *dir, const char *type, int fd) +{ + int res; + struct fuse_mount_data data; + + data.version = FUSE_MOUNT_VERSION; + data.fd = fd; + + res = mount(dev, dir, type, MS_MGC_VAL | MS_NOSUID | MS_NODEV, &data); + if(res == -1) { + perror("mount failed"); + return -1; + } + + return 0; +} + +static void add_mntent(const char *dev, const char *dir, const char *type) +{ + int res; + FILE *fp; + struct mntent ent; + + fp = setmntent("/etc/mtab", "a"); + if(fp == NULL) { + perror("setmntent"); + return; + } + + ent.mnt_fsname = (char *) dev; + ent.mnt_dir = (char *) dir; + ent.mnt_type = (char *) type; + ent.mnt_opts = "rw,nosuid,nodev"; + ent.mnt_freq = 0; + ent.mnt_passno = 0; + res = addmntent(fp, & ent); + if(res != 0) + perror("addmntent"); + + endmntent(fp); + +} + +static void remove_mntent(const char *dir) +{ + int res; + FILE *fdold, *fdnew; + struct mntent *entp; + + fdold = setmntent("/etc/mtab", "r"); + if(fdold == NULL) { + perror("/etc/mtab"); + return; + } + + fdnew = setmntent("/etc/mtab~", "w"); + if(fdnew == NULL) { + perror("/etc/mtab~"); + return; + } + + do { + entp = getmntent(fdold); + if(entp != NULL && strcmp(entp->mnt_dir, dir) != 0) { + res = addmntent(fdnew, entp); + if(res != 0) + perror("addmntent"); + } + } while(entp != NULL); + + endmntent(fdold); + endmntent(fdnew); + + res = rename("/etc/mtab~", "/etc/mtab"); + if(res == -1) + perror("renameing /etc/mtab~ to /etc/mtab"); +} + +int fuse_mount(struct fuse *f, const char *dir) +{ + int res; + const char *dev = FUSE_DEV; + const char *type = "fuse"; + + if(f->dir != NULL) + return 0; + + f->dir = g_strdup(dir); + f->fd = open(dev, O_RDWR); + if(f->fd == -1) { + perror(dev); + return -1; + } + + res = do_mount(dev, dir, type, f->fd); + if(res == -1) + return -1; + + add_mntent(dev, dir, type); + + return 0; +} + +int fuse_unmount(struct fuse *f) +{ + int res; + + if(f->dir == NULL) + return 0; + + close(f->fd); + f->fd = -1; + + res = umount(f->dir); + if(res == -1) + perror("umount failed"); + else + remove_mntent(f->dir); + + g_free(f->dir); + f->dir = NULL; + + return res; +} |