#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <mntent.h>
+#include <sys/mount.h>
-/* Assumed length of a line in /etc/mtab */
-#define MTAB_LINE 160
+static int err = 0;
+static int all = 0;
+static char *fstype = "fuzix";
-int lsmtab(void)
+static void usage(void)
+{
+ fputs("Usage: mount [-a] [-t type] name [path].\n", stderr);
+ exit(1);
+}
+
+static int lsmtab(void)
{
FILE *f;
- char tmp[MTAB_LINE];
- char* dev;
- char* mntpt;
- char* fstype;
- char* rwflag;
+ struct mntent *mnt;
- f = fopen("/etc/mtab", "r");
+ f = setmntent("/etc/mtab", "r");
if (f) {
- while (fgets(tmp, sizeof(tmp), f)) {
- dev = strtok(tmp, " ");
- mntpt = strtok(NULL, " ");
- fstype = strtok(NULL, " ");
- rwflag = strtok(NULL, "\n");
- if (strcmp(fstype, "swap") == 0)
- printf("%s is swapspace\n", dev);
+ while (mnt = getmntent(f)) {
+ if (strcmp(mnt->mnt_type, "swap") == 0)
+ printf("%s is swapspace\n", mnt->mnt_fsname);
else
- printf("%s mounted on %s read-%s\n", dev, mntpt,
- (strcmp(rwflag, "ro") == 0) ? "only" : "write");
+ printf("%s mounted on %s read-%s\n",
+ mnt->mnt_fsname,
+ mnt->mnt_dir,
+ hasmntopt(mnt, "ro") ? "only" : "write");
}
- fclose(f);
- }
+ endmntent(f);
+ } else
+ err = 1;
return 0;
}
-int add2mtab(char *dev, char *mntpt, char *fstype, char *rwflag)
+static void add2mtab(struct mntent *mnt)
{
- FILE *inpf, *outf;
- char *tmp_fname;
- int c;
+ FILE *f;
- if ((tmp_fname = tmpnam(NULL)) == NULL) {
- perror("Error getting temporary file name");
- exit(1);
- }
- inpf = fopen("/etc/mtab", "r");
- outf = fopen(tmp_fname, "w");
- if (!outf) {
- perror("Can't create temporary file");
+ f = setmntent("/etc/mtab", "a");
+ if (f == NULL) {
+ perror("/etc/mtab");
exit(1);
}
- if (inpf) {
- for (;;) {
- c = fgetc(inpf);
- if (c == EOF)
- break;
- fputc(c, outf);
+ addmntent(f, mnt);
+ endmntent(f);
+}
+
+static int flagsof(struct mntent *mnt)
+{
+ int f = 0;
+ if (hasmntopt(mnt, "ro"))
+ f |= MS_RDONLY;
+ if (hasmntopt(mnt, "nosuid"))
+ f |= MS_NOSUID;
+ return f;
+}
+
+static int is_mounted(struct mntent *ent)
+{
+ FILE *f = setmntent("/etc/mtab", "r");
+ struct mntent mnt;
+ static char buf[_MAX_MNTLEN];
+
+ while(getmntent_r(f, &mnt, buf, _MAX_MNTLEN)) {
+ if (strcmp(mnt.mnt_fsname, ent->mnt_fsname) == 0) {
+ endmntent(f);
+ return 1;
}
- fclose(inpf);
}
- fprintf(outf, "%s %s %s %s\n", dev, mntpt, fstype, rwflag);
- fclose(outf);
- if (inpf && unlink("/etc/mtab") < 0) {
- perror("Can't delete old /etc/mtab file");
- exit(1);
+ endmntent(f);
+ return 0;
+}
+
+static void do_mount(struct mntent *mnt)
+{
+ if (strcmp(mnt->mnt_type, "swap") == 0)
+ return;
+ if (mount(mnt->mnt_fsname, mnt->mnt_dir, flagsof(mnt)) == -1) {
+ err = errno;
+ perror(mnt->mnt_fsname);
+ return;
}
- if (rename(tmp_fname, "/etc/mtab") < 0) {
- perror("Error installing /etc/mtab");
- exit(1);
+ add2mtab(mnt);
+}
+
+static void automount(char *match)
+{
+ FILE *f = setmntent("/etc/fstab", "r");
+ struct mntent *mnt;
+
+ while (mnt = getmntent(f)) {
+ /* Warning - mnt contents go invalid if we do work on mtab so
+ be careful here and use getmntent_r in is_mounted */
+ if (is_mounted(mnt))
+ continue;
+ if (match == NULL || strcmp(mnt->mnt_fsname, match) == 0 ||
+ strcmp(mnt->mnt_dir, match) == 0)
+ do_mount(mnt);
+ if (err)
+ break;
}
- return 0;
+ endmntent(f);
}
int main(int argc, char *argv[])
{
- if (argc == 1) {
- lsmtab();
- return 0;
- }
+ int opt;
- if (argc != 3) {
- printf("usage: mount device path\n");
- return 1;
+ while((opt = getopt(argc, argv, "at:")) != -1) {
+ if (opt == 'a')
+ all = 1;
+ else if (opt == 't')
+ fstype = optarg;
+ else
+ usage();
}
- if (mount(argv[1], argv[2], 0) == 0) {
- add2mtab(argv[1], argv[2], "uzi", "rw");
- } else {
- perror("mount");
- return 1;
+ if (optind >= argc) {
+ if (all)
+ automount(NULL);
+ else
+ lsmtab();
+ return err;
}
- return 0;
+ if (optind == argc - 1)
+ automount(argv[optind]);
+ else if (optind <= argc - 2) {
+ static struct mntent mnt;
+ mnt.mnt_fsname = argv[optind++];
+ mnt.mnt_dir = argv[optind++];
+ mnt.mnt_type = fstype;
+ if (optind != argc)
+ mnt.mnt_opts = argv[optind++];
+ if (optind != argc)
+ usage();
+ do_mount(&mnt);
+ }
+ return err;
}
#include <string.h>
#include <stdlib.h>
#include <sys/mount.h>
+#include <mntent.h>
/* Assumed length of a line in /etc/mtab */
+/* FIXME */
#define MTAB_LINE 160
#define MAXFS 16
static char *devlist[MAXFS];
static char **devp = &devlist[0];
-static char tmp[MTAB_LINE];
-
-const char *readmtab(FILE *fp)
-{
- char *dev;
- while (fgets(tmp, sizeof(tmp), fp) != NULL) {
- dev = strtok(tmp, " \t");
- if (dev == NULL || *tmp == '#')
- continue;
- return dev;
- }
- return NULL;
-}
-
-char *getdev(char *arg)
+static char *getdev(char *arg)
{
FILE *f;
- const char *dev;
- char* mntpt;
+ struct mntent *mnt;
- f = fopen("/etc/mtab", "r");
+ f = setmntent("/etc/mtab", "r");
if (f) {
- while ((dev = readmtab(f)) != NULL) {
- mntpt = strtok(NULL, " \t");
- if ((strcmp(dev, arg) == 0) || (strcmp(mntpt, arg) == 0)) {
- fclose(f);
- return strdup(dev);
+ while (mnt = getmntent(f)) {
+ if ((strcmp(mnt->mnt_fsname, arg) == 0) || (strcmp(mnt->mnt_dir, arg) == 0)) {
+ endmntent(f);
+ return strdup(mnt->mnt_fsname);
}
}
- fclose(f);
+ endmntent(f);
}
return NULL;
}
-int deleted(const char *p)
+static int deleted(const char *p)
{
char **d = &devlist[0];
}
/* FIXME: error checking, atomicity */
-int rewrite_mtab(void)
+static int rewrite_mtab(void)
{
FILE *inpf, *outf;
- char *tmp_fname;
- static char tmp[MTAB_LINE];
- static char tmp2[MTAB_LINE];
- char* dev;
+ struct mntent *mnt;
- inpf = fopen("/etc/mtab", "r");
+ inpf = setmntent("/etc/mtab", "r");
if (!inpf) {
perror("Can't open /etc/mtab");
exit(1);
}
- outf = fopen("/etc/mtab.new", "w");
+ outf = setmntent("/etc/mtab.new", "w");
if (!outf) {
perror("Can't create temporary file");
exit(1);
}
- while (fgets(tmp, sizeof(tmp), inpf)) {
- strncpy( tmp2, tmp, MTAB_LINE );
- dev = strtok(tmp, " \t");
- if (dev && deleted(dev)) {
+ while (mnt = getmntent(inpf)) {
+ /* FIXME: should we check device and dir ? */
+ if (deleted(mnt->mnt_fsname))
continue;
- } else {
- fputs(tmp2, outf);
- }
+ else
+ addmntent(outf, mnt);
}
- fclose(inpf);
- fclose(outf);
+ endmntent(inpf);
+ endmntent(outf);
if (rename("/etc/mtab.new", "/etc/mtab") < 0) {
perror("Error installing /etc/mtab");
exit(1);
int main(int argc, char *argv[])
{
+ struct mntent *mnt;
const char *dev;
char **dp;
FILE *f;
if (strcmp(argv[1], "-a") == 0) {
/* We need to umount things in reverse order if we have
mounts on mounts */
- f = fopen("/etc/mtab", "r");
+ f = setmntent("/etc/mtab", "r");
if (f == NULL) {
perror("mtab");
exit(1);
}
- while((dev = readmtab(f)) != NULL) {
- char *mntpt = strtok(NULL, " \t");
+ while(mnt = getmntent(f)) {
/* We can't unmount / */
- if (strcmp(mntpt, "/"))
- queue_rm_mtab(dev);
+ if (strcmp(mnt->mnt_dir, "/"))
+ queue_rm_mtab(mnt->mnt_fsname);
}
- fclose(f);
+ endmntent(f);
dp = devp;
/* Unmount in reverse order of mounting */
while(--dp >= devlist) {