Introduction
Introduction Statistics Contact Development Disclaimer Help
mount: helper support + improvements - ubase - suckless linux base utils
git clone git://git.suckless.org/ubase
Log
Files
Refs
README
LICENSE
---
commit 71da5628d18492f48369d0d00cd86551ec7798d0
parent ee5b04a7a3d12e8eeac9c9aa0f1ea45e644f854a
Author: Hiltjo Posthuma <[email protected]>
Date: Sun, 10 May 2015 18:19:15 +0200
mount: helper support + improvements
- helper support (mount.type).
- helpers need to be in $PATH, if needed we can add a check for
/sbin/mount.XXXX
- pass -B, -M, -R to helper, its more reliable to pass these named
options with -o however.
- allow prefix "no" for which type no action should be taken:
mount -a -t nonfs,ext4
fix bugs:
- dont modify me->mnt_opts (used strtok).
Diffstat:
M mount.8 | 18 +++++++++++++++++-
M mount.c | 153 ++++++++++++++++++++++++-----…
2 files changed, 139 insertions(+), 32 deletions(-)
---
diff --git a/mount.8 b/mount.8
@@ -36,7 +36,23 @@ This is the default action.
.It Fl o Ar options
Specify a comma separated string of filesystem specific options.
.It Fl t Ar fstype
-Set the filesystem type.
+Set the filesystem type. More than one type may be specified in a comma
+separated list. The list of file system types can be prefixed with "no" to
+specify the file system types for which action should not be taken. For
+example, the
+.Nm
+command:
+.Bd -literal
+# mount -a -t nonfs,ext4
+
+.Ed
+mounts all file systems except those of type NFS and EXT4.
+.Nm
+will attempt to execute a program in your
+.Ev PATH
+mount.XXX where XXX is replaced by the type name. For example, NFS file
+systems are mounted by the program
+.Pa mount.nfs .
.El
.Sh SEE ALSO
.Xr mount 2 ,
diff --git a/mount.c b/mount.c
@@ -2,7 +2,9 @@
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
#include <limits.h>
#include <mntent.h>
#include <stdio.h>
@@ -34,41 +36,117 @@ struct {
{ NULL, NULL, 0 }
};
+static unsigned long argflags = 0;
+static char *argopts = NULL;
+
+static char *
+findtype(const char *types, const char *t)
+{
+ const char *p;
+ size_t len;
+
+ for (len = strlen(t); (p = strstr(types, t)); types = p + len) {
+ if (!strncmp(p, t, len) && (p[len] == '\0' || p[len] == ','))
+ return (char *)p;
+ }
+ return NULL;
+}
+
static void
-parseopts(char *popts, unsigned long *flags, char *data, size_t datasiz)
+parseopts(const char *popts, unsigned long *flags, char *data, size_t datasiz)
{
unsigned int i, validopt;
size_t optlen, dlen = 0;
- char *name;
+ const char *name, *e;
+ name = popts;
data[0] = '\0';
- for (name = strtok(popts, ","); name; name = strtok(NULL, ",")) {
+ do {
+ if ((e = strstr(name, ",")))
+ optlen = e - name;
+ else
+ optlen = strlen(name);
+
validopt = 0;
for (i = 0; optnames[i].opt; i++) {
- if (optnames[i].opt && strcmp(name, optnames[i].opt) =…
+ if (optnames[i].opt &&
+ !strncmp(name, optnames[i].opt, optlen)) {
*flags |= optnames[i].v;
validopt = 1;
break;
}
- if (optnames[i].notopt && strcmp(name, optnames[i].not…
+ if (optnames[i].notopt &&
+ !strncmp(name, optnames[i].notopt, optlen)) {
*flags &= ~optnames[i].v;
validopt = 1;
break;
}
}
- if (!validopt) {
+
+ if (!validopt && optlen > 0) {
/* unknown option, pass as data option to mount() */
- if ((optlen = strlen(name))) {
- if (dlen + optlen + 2 >= datasiz)
- return; /* prevent overflow */
- if (dlen)
- data[dlen++] = ',';
- memcpy(&data[dlen], name, optlen);
- dlen += optlen;
- data[dlen] = '\0';
- }
+ if (dlen + optlen + 2 >= datasiz)
+ return; /* prevent overflow */
+ if (dlen)
+ data[dlen++] = ',';
+ memcpy(&data[dlen], name, optlen);
+ dlen += optlen;
+ data[dlen] = '\0';
+ }
+ name = e + 1;
+ } while (e);
+}
+
+static int
+mounthelper(const char *fsname, const char *dir, const char *fstype)
+{
+ pid_t pid;
+ char eprog[PATH_MAX];
+ char const *eargv[10];
+ int status, i;
+
+ pid = fork();
+ switch(pid) {
+ case -1:
+ break;
+ case 0:
+ snprintf(eprog, sizeof(eprog), "mount.%s", fstype);
+
+ i = 0;
+ eargv[i++] = eprog;
+ if (argflags & MS_BIND)
+ eargv[i++] = "-B";
+ if (argflags & MS_MOVE)
+ eargv[i++] = "-M";
+ if (argflags & MS_REC)
+ eargv[i++] = "-R";
+
+ if (argopts) {
+ eargv[i++] = "-o";
+ eargv[i++] = argopts;
+ }
+ eargv[i++] = fsname;
+ eargv[i++] = dir;
+ eargv[i] = NULL;
+
+ execvp(eprog, (char * const *)eargv);
+ if (errno == ENOENT)
+ _exit(1);
+ weprintf("execvp:");
+ _exit(1);
+ break;
+ default:
+ if (waitpid(pid, &status, 0) < 0) {
+ weprintf("waitpid:");
+ return -1;
}
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ else if (WIFSIGNALED(status))
+ return 1;
+ break;
}
+ return 0;
}
static int
@@ -96,6 +174,7 @@ mounted(const char *dir)
return 1;
}
endmntent(fp);
+
return 0;
}
@@ -103,37 +182,37 @@ static void
usage(void)
{
eprintf("usage: %s [-BMRan] [-t fstype] [-o options] [source] [target]…
- argv0);
+ argv0);
}
int
main(int argc, char *argv[])
{
- int aflag = 0, oflag = 0, status = 0, i;
- unsigned long flags = 0;
char *types = NULL, data[512] = "", *resolvpath = NULL;
char *files[] = { "/proc/mounts", "/etc/fstab", NULL };
- size_t datasiz = sizeof(data);
const char *source, *target;
struct mntent *me = NULL;
+ int aflag = 0, oflag = 0, status = 0, i, r;
+ unsigned long flags = 0;
FILE *fp;
ARGBEGIN {
case 'B':
- flags |= MS_BIND;
+ argflags |= MS_BIND;
break;
case 'M':
- flags |= MS_MOVE;
+ argflags |= MS_MOVE;
break;
case 'R':
- flags |= MS_REC;
+ argflags |= MS_REC;
break;
case 'a':
aflag = 1;
break;
case 'o':
oflag = 1;
- parseopts(EARGF(usage()), &flags, data, datasiz);
+ argopts = EARGF(usage());
+ parseopts(argopts, &flags, data, sizeof(data));
break;
case 't':
types = EARGF(usage());
@@ -182,7 +261,7 @@ main(int argc, char *argv[])
source = me->mnt_fsname;
}
if (!oflag)
- parseopts(me->mnt_opts, &flags, data, …
+ parseopts(me->mnt_opts, &flags, data, …
if (!types)
types = me->mnt_type;
goto mountsingle;
@@ -195,7 +274,10 @@ main(int argc, char *argv[])
eprintf("can't find %s in /etc/fstab\n", target);
mountsingle:
- if (mount(source, target, types, flags, data) < 0) {
+ r = mounthelper(source, target, types);
+ if (r == -1)
+ status = 1;
+ if (r > 0 && mount(source, target, types, argflags | flags, data) < 0)…
weprintf("mount: %s:", source);
status = 1;
}
@@ -208,14 +290,23 @@ mountall:
if (!(fp = setmntent("/etc/fstab", "r")))
eprintf("setmntent %s:", "/etc/fstab");
while ((me = getmntent(fp))) {
- if (hasmntopt(me, MNTOPT_NOAUTO))
- continue;
- /* already mounted, skip */
- if (mounted(me->mnt_dir))
+ /* has "noauto" option or already mounted: skip */
+ if (hasmntopt(me, MNTOPT_NOAUTO) || mounted(me->mnt_dir))
continue;
flags = 0;
- parseopts(me->mnt_opts, &flags, data, datasiz);
- if (mount(me->mnt_fsname, me->mnt_dir, me->mnt_type, flags, da…
+ parseopts(me->mnt_opts, &flags, data, sizeof(data));
+ /* if -t types specified:
+ * if non-match, skip
+ * if match and prefixed with "no", skip */
+ if (types &&
+ ((types[0] == 'n' && types[1] == 'o' &&
+ findtype(types + 2, me->mnt_type)) ||
+ (!findtype(types, me->mnt_type))))
+ continue;
+
+ r = mounthelper(me->mnt_fsname, me->mnt_dir, me->mnt_type);
+ if (r > 0 && mount(me->mnt_fsname, me->mnt_dir, me->mnt_type,
+ argflags | flags, data) < 0) {
weprintf("mount: %s:", me->mnt_fsname);
status = 1;
}
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.