---
 umount.8 |  5 +++++
 umount.c | 60 +++++++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/umount.8 b/umount.8
index c172efb..1309b24 100644
--- a/umount.8
+++ b/umount.8
@@ -11,6 +11,7 @@
 .Nm
 .Op Fl fln
 .Fl a
+.Op Fl t Ar fstypes
 .Sh DESCRIPTION
 .Nm
 detaches the
@@ -34,6 +35,10 @@ all references to the filesystem as soon as it is not busy 
anymore.
 Unmount without writing in
 .Pa /etc/mtab .
 This is the default action.
+.It Fl t Ar fstypes
+Only act on file systems with types matching those in the comma separated list
+fstypes. This list can be prefixed with "no" to act on all filesystems types
+except those in the list.
 .El
 .Sh SEE ALSO
 .Xr umount 2 ,
diff --git a/umount.c b/umount.c
index c6d6d9a..55823f5 100644
--- a/umount.c
+++ b/umount.c
@@ -9,24 +9,48 @@
 #include "util.h"
 
 static int
-umountall(int flags)
+matchtype(char *type, char *list)
 {
-       FILE *fp;
-       struct mntent *me;
-       int ret = 0;
-       char **mntdirs = NULL;
-       int len = 0;
+    int invert = 0;
+
+    if (memcmp(list, "no", 2) == 0) {
+        invert = 1;
+        list += 2;
+    }
+
+    if (*list == ',')
+        list++;
+
+    while (list) {
+        if (memcmp(type, list, strlen(type)) == 0)
+            return !invert;
+
+        if ((list = strchr(list, ',')) != NULL)
+            list++;
+    }
+
+    return invert;
+}
+
+static int
+umounttype(int flags, char *list)
+{
+    FILE *fp;
+    struct mntent *me;
+    int ret = 0;
+    char **mntdirs = NULL;
+    int len = 0;
 
-       fp = setmntent("/proc/mounts", "r");
-       if (!fp)
+    fp = setmntent("/proc/mounts", "r");
+    if (!fp)
                eprintf("setmntent %s:", "/proc/mounts");
        while ((me = getmntent(fp))) {
-               if (strcmp(me->mnt_type, "proc") == 0)
-                       continue;
-               mntdirs = erealloc(mntdirs, ++len * sizeof(*mntdirs));
-               mntdirs[len - 1] = estrdup(me->mnt_dir);
-       }
-       endmntent(fp);
+        if (matchtype(me->mnt_type, list)) {
+            mntdirs = erealloc(mntdirs, ++len * sizeof(*mntdirs));
+            mntdirs[len - 1] = estrdup(me->mnt_dir);
+        }
+    }
+    endmntent(fp);
        while (--len >= 0) {
                if (umount2(mntdirs[len], flags) < 0) {
                        weprintf("umount2 %s:", mntdirs[len]);
@@ -42,7 +66,7 @@ static void
 usage(void)
 {
        weprintf("usage: %s [-lfn] target...\n", argv0);
-       weprintf("usage: %s -a [-lfn]\n", argv0);
+       weprintf("usage: %s -a [-lfn] [-t fstype]\n", argv0);
        exit(1);
 }
 
@@ -53,6 +77,7 @@ main(int argc, char *argv[])
        int aflag = 0;
        int flags = 0;
        int ret = 0;
+    char *typelist = NULL;
 
        ARGBEGIN {
        case 'a':
@@ -66,6 +91,9 @@ main(int argc, char *argv[])
                break;
        case 'n':
                break;
+       case 't':
+        typelist = EARGF(usage());
+               break;
        default:
                usage();
        } ARGEND;
@@ -74,7 +102,7 @@ main(int argc, char *argv[])
                usage();
 
        if (aflag == 1)
-               return umountall(flags);
+               return umounttype(flags, typelist ? typelist : "no");
 
        for (i = 0; i < argc; i++) {
                if (umount2(argv[i], flags) < 0) {
-- 
2.30.0


Reply via email to