[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#426879: pmount list-mounts patch



Package: pmount
Version: 0.9.13
Severity: wishlist
Tags: patch

Hello,

I am using pmount on my computers for mounting of removable devices.
However, I'm missing one feature: displaying a list of mounted removable
devices. So I've made it myself :-).

Other people might be interested in it as well, so I'm sending in the patch (see 
attch.).

After applying the patch, pmount will print mounted removable devices if
it is run without arguments. The new behaviour is similar to that of
'mount' command, but pmount will only list removable devices.
                                                                                                                                 
Hope this helps.
                                                                                                                                 
Best regards,
Dan Keder

--
Dan Keder
http://www.fi.muni.cz/~xkeder/
------------------------------------------------
diff -Naur pmount-0.9.13/src/pmount.c pmount-0.9.14/src/pmount.c
--- pmount-0.9.13/src/pmount.c	2006-08-15 22:47:45.000000000 +0200
+++ pmount-0.9.14/src/pmount.c	2007-05-29 23:03:08.000000000 +0200
@@ -484,6 +484,21 @@
     drop_root();
 }
 
+void 
+print_mounted_devs()
+{
+    struct mnt_entry mnt_entries[255];
+    int size;
+    int i;
+
+    size = list_mounts( "/proc/mounts", mnt_entries, 255);
+
+    for( i = 0; i < size; i++ ) {
+        if( mnt_entries[i].removable )
+            printf( "%s on %s\n", mnt_entries[i].mnt_device, mnt_entries[i].mnt_dir ); 
+    }
+}
+
 /**
  * Entry point.
  */
@@ -582,6 +597,12 @@
         }
     } while( option != -1 );
 
+    /* print list of mounted devices */
+    if( argc == 1 ) {
+        print_mounted_devs();
+        return 0;
+    }
+
     /* determine device and second (label/pid) argument */
     if( optind < argc )
         devarg = argv[optind];
diff -Naur pmount-0.9.13/src/policy.c pmount-0.9.14/src/policy.c
--- pmount-0.9.13/src/policy.c	2006-08-15 23:00:37.000000000 +0200
+++ pmount-0.9.14/src/policy.c	2007-05-29 22:59:04.000000000 +0200
@@ -226,6 +226,64 @@
     return value == '1';
 }
 
+int
+_device_removable( const char* device )
+{
+    struct sysfs_device *dev;
+    static char* hotplug_buses[] = { "usb", "ieee1394", "mmc", "pcmcia", NULL };
+    int removable;
+    char blockdevpath[PATH_MAX];
+
+    dev = find_sysfs_device( device, blockdevpath, sizeof( blockdevpath ) );
+    if( !dev ) {
+        debug( "device_removable: could not find a sysfs device for %s\n", device );
+        return 0; 
+    }
+
+    debug( "device_removable: corresponding block device for %s is %s\n",
+                device, blockdevpath );
+
+    /* check whether device has "removable" attribute with value '1' */
+    removable = get_blockdev_attr( blockdevpath, "removable" );
+
+    /* if not, fall back to bus scanning (regard USB and FireWire as removable) */
+    if( !removable )
+        removable = find_bus_ancestry( dev, hotplug_buses );
+    sysfs_close_device( dev );
+
+    return removable;
+}
+
+int
+_device_valid( const char* device )
+{
+    struct stat st;
+
+    if( stat( device, &st ) ) {
+        return 0;
+    }
+
+    if( !S_ISBLK( st.st_mode ) ) {
+        return 0;
+    }
+
+    return 1;
+}
+
+int 
+_get_uid_opt( const struct mntent* ent )
+{
+    char* uidopt;
+    int uid;
+
+    uidopt = hasmntopt( ent, "uid" );
+    if( uidopt ) {
+        sscanf(uidopt, "uid=%d", &uid);
+    } else
+        uid = -1;
+    return uid;
+}
+
 /*************************************************************************
  *
  * Policy functions
@@ -250,6 +308,45 @@
     return 1;
 }
 
+int
+list_mounts( const char* fname, struct mnt_entry* entries, int max_size )
+{
+    FILE* f;
+    struct mntent* ent;
+    struct mnt_entry entry;
+    char pathbuf[PATH_MAX];
+    int removable;
+    int index;
+
+    index = 0;
+
+    if( !( f = fopen( fname, "r" ) ) ) {
+        perror( _("Error: could not open fstab-type file") );
+        exit( 100 );
+    }
+    
+    while( ( ent = getmntent( f ) ) != NULL ) {
+        if( index >= max_size )
+            break;
+
+        snprintf( entry.mnt_device, sizeof( entry.mnt_device ), "%s", ent->mnt_fsname );
+        snprintf( entry.mnt_dir, sizeof( entry.mnt_dir ), "%s", ent->mnt_dir );
+
+        if( realpath( entry.mnt_device, pathbuf ) )
+            strncpy( entry.mnt_device, pathbuf, MAX_LABEL_SIZE );
+
+        if( _device_valid( entry.mnt_device ) ) {
+            entry.uid = _get_uid_opt( ent );
+            entry.removable = _device_removable ( entry.mnt_device );
+            memcpy( &entries[index], &entry, sizeof(entry) );
+            index++;
+        }
+    }
+    endmntent( f );
+
+    return index;
+}
+
 const char*
 fstab_has_device( const char* fname, const char* device, char* mntpt, int *uid )
 {
@@ -362,30 +459,14 @@
     return mounted;
 }
 
+
+
 int
 device_removable( const char* device )
 {
-    struct sysfs_device *dev;
-    static char* hotplug_buses[] = { "usb", "ieee1394", "mmc", "pcmcia", NULL };
     int removable;
-    char blockdevpath[PATH_MAX];
-
-    dev = find_sysfs_device( device, blockdevpath, sizeof( blockdevpath ) );
-    if( !dev ) {
-        debug( "device_removable: could not find a sysfs device for %s\n", device );
-        return 0; 
-    }
-
-    debug( "device_removable: corresponding block device for %s is %s\n",
-                device, blockdevpath );
 
-    /* check whether device has "removable" attribute with value '1' */
-    removable = get_blockdev_attr( blockdevpath, "removable" );
-
-    /* if not, fall back to bus scanning (regard USB and FireWire as removable) */
-    if( !removable )
-        removable = find_bus_ancestry( dev, hotplug_buses );
-    sysfs_close_device( dev );
+    removable = _device_removable( device );
 
     if( !removable )
         fprintf( stderr, _("Error: device %s is not removable\n"), device );
@@ -402,7 +483,7 @@
     regex_t re;
     regmatch_t match[3];
     int result;
-    const char* whitelist_regex = "^[[:space:]]*([[:alnum:]/_+.\-]+)[[:space:]]*(#.*)?$";
+    const char* whitelist_regex = "^[[:space:]]*([[:alnum:]/_+.\\-]+)[[:space:]]*(#.*)?$";
 
     fwl = fopen( WHITELIST, "r" );
     if( !fwl )
diff -Naur pmount-0.9.13/src/policy.h pmount-0.9.14/src/policy.h
--- pmount-0.9.13/src/policy.h	2006-08-08 11:31:59.000000000 +0200
+++ pmount-0.9.14/src/policy.h	2007-05-29 22:56:30.000000000 +0200
@@ -13,12 +13,33 @@
 
 #include <config.h>
 #include <stdlib.h> /* for size_t */
+#include <mntent.h> /* for mntent */
 
 #define MAX_LABEL_SIZE 255
 #define DEVDIR "/dev/"
 
 #define MEDIA_STRING_SIZE MAX_LABEL_SIZE + sizeof( MEDIADIR )
 
+struct mnt_entry
+{
+    char mnt_device[MAX_LABEL_SIZE];
+    char mnt_dir[MAX_LABEL_SIZE];
+    int uid;
+    int removable;
+};
+
+/**
+ * Get list of removable devices, that are mounted by the current user.
+ * The mount entries will be saved do mnt_entries.
+ *
+ * @param fname file of the fstab-type file to check
+ * @param mnt_entries array for storing the returned list of mount
+ *        entries
+ * @param max_size max size of mnt_entries
+ * @return number of entries stored in mnt_entries
+ */
+int list_mounts( const char* fname, struct mnt_entry* entries, int max_size );
+
 /**
  * Check whether a fstab-type file (fstab, /etc/mtab or /proc/mounts)
  * contains a device. Exits the program if file could not be opened.

Reply to: