├── automount.conf ├── automount-1.3.1.tar.gz ├── automount-1.4.1.tar.gz ├── automount-1.4.2.tar.gz ├── automount-1.4.3.tar.gz ├── automount-1.5.1.tar.gz ├── automount-1.5.2.tar.gz ├── automount-1.5.3.tar.gz ├── automount-1.5.4.tar.gz ├── automount-1.5.5.tar.gz ├── automount-1.5.7.tar.gz ├── automount-1.5.8.tar.gz ├── automount-1.5.9.tar.gz ├── automount-1.6.0.tar.gz ├── automount-1.6.1.tar.gz ├── automount-1.7.0.tar.gz ├── automount-1.7.1.tar.gz ├── automount-1.7.2.tar.gz ├── automount_devd_DEBUG.conf ├── automount_devd.conf ├── README └── automount /automount.conf: -------------------------------------------------------------------------------- 1 | USERUMOUNT=YES 2 | 3 | 4 | -------------------------------------------------------------------------------- /automount-1.3.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.3.1.tar.gz -------------------------------------------------------------------------------- /automount-1.4.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.4.1.tar.gz -------------------------------------------------------------------------------- /automount-1.4.2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.4.2.tar.gz -------------------------------------------------------------------------------- /automount-1.4.3.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.4.3.tar.gz -------------------------------------------------------------------------------- /automount-1.5.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.5.1.tar.gz -------------------------------------------------------------------------------- /automount-1.5.2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.5.2.tar.gz -------------------------------------------------------------------------------- /automount-1.5.3.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.5.3.tar.gz -------------------------------------------------------------------------------- /automount-1.5.4.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.5.4.tar.gz -------------------------------------------------------------------------------- /automount-1.5.5.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.5.5.tar.gz -------------------------------------------------------------------------------- /automount-1.5.7.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.5.7.tar.gz -------------------------------------------------------------------------------- /automount-1.5.8.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.5.8.tar.gz -------------------------------------------------------------------------------- /automount-1.5.9.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.5.9.tar.gz -------------------------------------------------------------------------------- /automount-1.6.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.6.0.tar.gz -------------------------------------------------------------------------------- /automount-1.6.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.6.1.tar.gz -------------------------------------------------------------------------------- /automount-1.7.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.7.0.tar.gz -------------------------------------------------------------------------------- /automount-1.7.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.7.1.tar.gz -------------------------------------------------------------------------------- /automount-1.7.2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probonopd/automount/master/automount-1.7.2.tar.gz -------------------------------------------------------------------------------- /automount_devd_DEBUG.conf: -------------------------------------------------------------------------------- 1 | notify 200 { 2 | match "system" "DEVFS"; 3 | match "type" "CREATE"; 4 | match "cdev" "(da|mmcsd)[0-9]+.*"; 5 | action "/bin/sh -xe /usr/local/sbin/automount $cdev attach >> /root/DEBUG.$cdev.attach 2>&1"; 6 | }; 7 | 8 | notify 200 { 9 | match "system" "DEVFS"; 10 | match "type" "DESTROY"; 11 | match "cdev" "(da|mmcsd)[0-9]+.*"; 12 | action "/bin/sh -xe /usr/local/sbin/automount $cdev detach >> /root/DEBUG.$cdev.detach 2>&1"; 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /automount_devd.conf: -------------------------------------------------------------------------------- 1 | 2 | # PENDRIVE/PHONE/SDCARD insert 3 | notify 100 { 4 | match "system" "DEVFS"; 5 | match "type" "CREATE"; 6 | match "cdev" "(da|mmcsd|ugen)[0-9]+.*"; 7 | action "/usr/local/sbin/automount $cdev attach &"; 8 | }; 9 | 10 | # PENDRIVE/PHONE/SDCARD remove 11 | notify 100 { 12 | match "system" "DEVFS"; 13 | match "type" "DESTROY"; 14 | match "cdev" "(da|mmcsd|ugen)[0-9]+.*"; 15 | action "/usr/local/sbin/automount $cdev detach &"; 16 | }; 17 | 18 | # CD-ROM media inject 19 | notify 100 { 20 | match "system" "DEVFS"; 21 | match "type" "CREATE|MEDIACHANGE"; 22 | match "cdev" "(cd)[0-9]+.*"; 23 | action "/usr/local/sbin/automount $cdev attach &"; 24 | }; 25 | 26 | # CD-ROM media eject 27 | notify 100 { 28 | match "system" "DEVFS"; 29 | match "type" "DESTROY"; 30 | match "cdev" "(cd)[0-9]+.*"; 31 | action "/usr/local/sbin/automount $cdev detach &"; 32 | }; 33 | 34 | # CD-ROM no media 35 | notify 100 { 36 | match "system" "CAM"; 37 | match "subsystem" "periph"; 38 | match "type" "error"; 39 | match "cam_status" "0xcc"; 40 | match "scsi_status" "2"; 41 | match "scsi_sense" "70 02 3a 02"; 42 | match "device" "(cd)[0-9]+.*"; 43 | action "/usr/local/sbin/automount $device detach &"; 44 | }; 45 | 46 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | ___ /\ ___ 3 | __/ /_ / \ _\ \__ 4 | ____ _____/_ __/__ / _/\ ___ ___ ____ ______ __\__ _\ 5 | / \ / / // // \ /\_/ \ / / \ / \\ \ \ / \\ \ 6 | / / // / // // / // \\ \ \ \\ \ \\ \ \\ \ \\ \_ 7 | \_____\\____/ \__\\____//__________\\__\__\__\\____/ \_____\\__\__\\___\ 8 | 9 | The 'automount' is a devd(8) based automounter for FreeBSD. 10 | 11 | It supports most popular file systems: 12 | NTFS/MSDOS/exFAT/EXT2/EXT3/EXT4/UFS/XFS/HFS/MTP/ISO9660 13 | 14 | ------------------------------------------------------------------------------- 15 | 16 | I N S T A L L 17 | =================== 18 | 19 | Use provided FreeBSD Ports/packages from here: 20 | * sysutils/automount 21 | 22 | .. or make manual unstallation: 23 | 24 | # cp automount.conf /usr/local/etc/automount.conf 25 | # cp automount_devd.conf /usr/local/etc/devd/automount_devd.conf 26 | # cp automount /usr/local/sbin/automount 27 | # chmod +x /usr/local/sbin/automount 28 | # /etc/rc.d/devd restart 29 | 30 | Now plugin Your USB thumb drive and have fun ;) 31 | 32 | These ports/packages are needed for all filesystems: 33 | 34 | * sysutils/exfat-utils // exFAT 35 | * sysutils/fusefs-exfat // exFAT 36 | * sysutils/fusefs-ntfs // NTFS (read write support) 37 | * sysutils/fusefs-ext2 // EXT4 38 | * sysutils/fusefs-hfsfuse // HFS 39 | * sysutils/fusefs-lkl // XFS 40 | * sysutils/fusefs-simple-mtpfs // MTP 41 | 42 | Regards, 43 | vermaden 44 | 45 | ------------------------------------------------------------------------------- 46 | 47 | C H A N G E L O G 48 | ========================= 49 | 50 | ------------------------------------------------------------------------------- 51 | 52 | VERSION 1.7.2 (CURRENT) 53 | 54 | Phase out support for sysutils/fusefs-ext4fuse port. 55 | Fix UMASK for exFAT filesystems. 56 | Fix ISO9660 mount options. 57 | 58 | ------------------------------------------------------------------------------- 59 | 60 | VERSION 1.7.1 61 | 62 | Fix exFAT mount rights. 63 | Use USER option in config file. 64 | Make MTP detection and mount better. 65 | 66 | ------------------------------------------------------------------------------- 67 | 68 | VERSION 1.7.0 69 | 70 | The automount has now a new co-author - Rozhuk Ivan. 71 | New options available in automount.conf config file. 72 | Filesystem detection/mounting reworked totally with file(1)/dd(1)/fstyp(8) as backends. 73 | Notifications are now possible with libnotify. 74 | Automatic detection of DISPLAY variable. 75 | New automatic wait for device appearance. 76 | New detection if device is a block device. 77 | Introduction of CD-ROM support. 78 | Automatic detection of File Manager with exo-open(1). 79 | Option REMOVEDIRS is deprecated now. 80 | Handle '-o large' option for FAT under FreeBSD 11.x and 12.x versions. 81 | 82 | ------------------------------------------------------------------------------- 83 | 84 | VERSION 1.6.1 85 | 86 | Fix MBR/msdosfs partition unmount issue. 87 | 88 | ------------------------------------------------------------------------------- 89 | 90 | VERSION 1.6.0 91 | 92 | Fix long boot with devd(8) because of ugen(4) devices. 93 | Add fsck.exfat to the exFAT filesystem. 94 | Set fsck.ext2 instead of e2fsck to the ext2 filesystem. 95 | Set fsck.ext3 instead of e2fsck to the ext3 filesystem. 96 | Set fsck.ext4 instead of e2fsck to the ext4 filesystem. 97 | 98 | ------------------------------------------------------------------------------- 99 | 100 | VERSION 1.5.9 101 | 102 | Decrease DELAY for sleep from '1' to '0.1' for faster mounting. 103 | Remove __random_wait() at 'attach'. 104 | Implement MTP mounting. 105 | Added XFS and HFS support. 106 | Various fixes and cleanups. 107 | Remove '-o large' option for FAT (not supported on FreeBSD 12). 108 | 109 | ------------------------------------------------------------------------------- 110 | 111 | VERSION 1.5.8 112 | 113 | Omit GVFS filesystem in the mount(8) listing. 114 | Improve exFAT mount options. 115 | Add mount_msdosfs(8) fallback fix. 116 | Set caja as file manager in example config. 117 | Add version argument. 118 | 119 | ------------------------------------------------------------------------------- 120 | 121 | VERSION 1.5.7 122 | 123 | Fix FAT32 mount. 124 | Add extended options for EXFAT mounts. 125 | Add -version option. 126 | 127 | ------------------------------------------------------------------------------- 128 | 129 | VERSION 1.5.6 130 | 131 | Implement --version option. 132 | 133 | ------------------------------------------------------------------------------- 134 | 135 | VERSION 1.5.5 136 | 137 | Rework NTFS/MSDOS/FAT detection. 138 | Check for NTFS before FAT. 139 | 140 | ------------------------------------------------------------------------------- 141 | 142 | VERSION 1.5.4 143 | 144 | Added notification via notify-send/libnotify and wall(1). Minor bug fix. 145 | Change 'boot sector' detection. 146 | 147 | ------------------------------------------------------------------------------- 148 | 149 | VERSION 1.5.3 150 | 151 | Fix small harmless bug - variable WAIT without default value. 152 | 153 | ------------------------------------------------------------------------------- 154 | 155 | VERSION 1.5.2 156 | 157 | Introduce smarter fstype() function to better determine filesystem. 158 | 159 | ------------------------------------------------------------------------------- 160 | 161 | VERSION 1.5.1 162 | 163 | Add -k flag to file(1) command. 164 | Set new --version and date(1). 165 | 166 | ------------------------------------------------------------------------------- 167 | 168 | VERSION 1.5.0 169 | 170 | Add new NTFS options. 171 | Add nested NTFS mount attempt. 172 | Fix devd(8) config. 173 | Improve log messages. 174 | Use random wait only on ATTACH action, not needed on DETACH action. 175 | Implement random wait to eliminate race. 176 | Implement BOOTDELAY option to wait for boot process to complete. 177 | Fix devd(8) config (LARKIND) to match all needed devices and their partitions. 178 | Fix typo in NTFS error message. 179 | 180 | ------------------------------------------------------------------------------- 181 | 182 | VERSION 1.4.3 183 | 184 | Only style(9) changes. 185 | Force longnames option for msdosfs. 186 | Remove -u option for debug. 187 | Fix a bug when ATIME is enabled. 188 | Add -o remove_hiberfile to NTFS-3G mount options. 189 | Fix typo at /var/log/automount.log error message. 190 | Use /sbin/e2fsck from FreeBSD base system. 191 | Fix typo at /var/log/automount.log error message. 192 | Force longnames option for msdosfs. 193 | 194 | ------------------------------------------------------------------------------- 195 | 196 | VERSION 1.4.2 197 | 198 | Implement active sleep/wait for devices that could not appear. 199 | Add more useful information to /var/log/automount.log file. 200 | Implement BLACKLIST option to ignore problematic devices. 201 | 202 | ------------------------------------------------------------------------------- 203 | 204 | VERSION 1.4.1 205 | 206 | Improved checking for already mounted devices. 207 | More readable log format. 208 | Added logging of fsck(8) output. 209 | Added adding setuid also to /sbin/mount* when USERUMOUNT set to YES. 210 | Added error logging of failed mounts. 211 | 212 | ------------------------------------------------------------------------------- 213 | 214 | VERSION 1.4.0 215 | 216 | Wait for smartphone to attach device, rewrite all &&-|| into if-then-else-fi syntax. 217 | 218 | ------------------------------------------------------------------------------- 219 | 220 | VERSION 1.3.1 221 | 222 | Fixed the 'detach' section (s/PREFIX/MNTPREFIX/g). 223 | Fixed removing directories of manually (properly) unmounted filesystems. 224 | 225 | ------------------------------------------------------------------------------- 226 | 227 | VERSION 1.3 228 | 229 | Fixed inproper exFAT detection, now mounts fine. 230 | Fixed creating mount dirs for attached devices no matter if needed or not. 231 | Revised 'detach' section, now removes only directory that is unmounted. 232 | Simplified FAT/NTFS sections, removed additional checks as they break 233 | some MP3 players automount. 234 | 235 | ------------------------------------------------------------------------------- 236 | 237 | VERSION 1.2.1 238 | 239 | Added the --help page. 240 | Removed some small bugs. 241 | Added more options to configure features. 242 | 243 | % /usr/local/sbin/automount --help 244 | AUTOMOUNT is a devd(8) based automounter for FreeBSD. 245 | 246 | It supports following file systems: 247 | UFS/FAT/exFAT/NTFS/EXT2/EXT3/EXT4/MTP/HFS/ISO9660 248 | 249 | Add these to mount NTFS/exFAT/EXT4/HFS/XFS/MTP respectively: 250 | o sysutils/fusefs-ntfs 251 | o sysutils/fusefs-exfat 252 | o sysutils/fusefs-ext4fuse 253 | o sysutils/fusefs-hfsfuse 254 | o sysutils/fusefs-lkl 255 | o sysutils/fusefs-simple-mtpfs 256 | 257 | By default it mounts/unmounts all removable media but 258 | it is possible to set some additional options at the 259 | /usr/local/etc/automount.conf config file. 260 | 261 | Below is a list of possible options with description. 262 | 263 | MNT_PREFIX (set to /media by default) 264 | With this options You can alter the default root 265 | for mounting the removable media, for example to 266 | the /mnt directory. 267 | 268 | example: MNT_PREFIX='/media' 269 | 270 | MNT_GROUP (wheel by default) 271 | If set to some group name, the mount command will 272 | chown(1) the mount directory with the group. 273 | 274 | example: group='operator' 275 | 276 | MNT_MODE (set to 775 by default) 277 | Value for chmod on mount point. 278 | 279 | FAT_ENCODING (set to en_US.UTF-8 by default) 280 | Only used with FAT32 mounts, specifies which 281 | encoding to use at the mount. 282 | 283 | example: FAT_ENCODING='en_US.ISO8859-1' 284 | 285 | FAT_CODEPAGE (set to CP866 by default) 286 | Only used with FAT32 mounts, specifies which 287 | code page to use at the mount. 288 | 289 | example: FAT_CODEPAGE='cp437' 290 | 291 | ISO9660_CODEPAGE (set to UTF-8 by default) 292 | Only used with cd9660 mounts, specifies which 293 | code page to use at the mount. 294 | 295 | ATIME (set to NO by default) 296 | When set to NO it will mount filesystems with 297 | noatime option when possible. 298 | 299 | example: ATIME='YES' 300 | 301 | RETRY_COUNT (set to 3 by default) 302 | How many times try to get file system type or try to mount. 303 | 304 | example: RETRY_COUNT='1' 305 | 306 | RETRY_DELAY (set to 1 second by default) 307 | Delay beetwin retry attempt. 308 | 309 | example: RETRY_DELAY='2.5' 310 | 311 | USERUMOUNT (set to NO by default) 312 | When set to YES it will 'chmod +s /sbin/umount' 313 | which would allow an USER to unmount the file 314 | system with their selected file manager. 315 | 316 | example: USERUMOUNT='YES' 317 | 318 | NOTIFY (set to NO by default) 319 | Use 'notify-send' and 'libnotify' to show notifications 320 | of mounting and unmounting devices on the desktop. 321 | 322 | example: NOTIFY='YES' 323 | 324 | WALL (set to NO by default) 325 | Use wall(1) to show notifications of mounting and 326 | unmounting devices on terminals of logged in users. 327 | 328 | example: WALL='YES' 329 | 330 | FM ('exo-open --launch FileManager' by default) 331 | If set to file manager command, the mount will 332 | launch the specified command after successful 333 | mount. Works only if USER parameter is also set. 334 | 335 | example: FM='nautilus --browser --no-desktop' 336 | 337 | BLACKLIST (unset by default) 338 | The automount will ignore devices defined here. 339 | 340 | example: BLACKLIST='da0 da3s1a' 341 | 342 | USER (root by default) 343 | If set to some username, the mount command will 344 | chown(1) the mount directory with the user and 345 | its primary user group. If used with FM option 346 | allows to launch the specified file manager after 347 | a successful mount. 348 | 349 | example: USER="vermaden" 350 | 351 | ------------------------------------------------------------------------------- 352 | 353 | VERSION 1.2 354 | 355 | FAT/NTFS detection improvements. 356 | The 'chown' now uses sets user's group. 357 | MSDOS filesystem is now mounted with -m 644 -M 755 options by default. 358 | Removed POPUP=YES option, just use USER + FM for simplicity. 359 | NTFS filesystem, when mounted by mount_ntfs(8) uses -u and -g options. 360 | Even more simplified 'detach' section. 361 | 362 | ------------------------------------------------------------------------------ 363 | 364 | VERSION 1.1 365 | 366 | I removed the state_lock and stat_unlock mechanisms as they appeared to be 367 | not needed, I have shufled with 3 drives all the time and the 'integrity' 368 | has not been lost, at it was a lot faster, because the lock always had to 369 | wait for the 'slowest' drive (in term of initializing the device, like USB 370 | hard drive). 371 | 372 | I simplified the 'attach' section a lot, now each filesystem contains only 373 | check/fsck (if possible), mount and log info. 374 | 375 | I also simplified and improved the 'detach' section a little. 376 | 377 | I added an option to automatically launch the set-up in config file manager. 378 | 379 | These are options that I currently successfully use for NAUTILUS file 380 | manager. You need to set-up all three of them to make it work. 381 | 382 | | POPUP=YES 383 | | FM="nautilus --browser --no-desktop" 384 | | USER=vermaden 385 | 386 | My whole config looks like that now: 387 | 388 | | USERUMOUNT=YES 389 | | POPUP=YES 390 | | FM="nautilus --browser --no-desktop" 391 | | USER=vermaden 392 | | ENCODING=pl_PL.ISO8859-2 393 | | CODEPAGE=cp852 394 | 395 | All latest updates are available at GITHUB repository: 396 | https://github.com/vermaden/automount 397 | 398 | ------------------------------------------------------------------------------ 399 | 400 | VERSION 1.0 401 | 402 | AUTOMOUNT is devd(8) based flexible yet very simple automounter for FreeBSD. 403 | 404 | Currently it supports these file systems: 405 | -- NTFS requires sysutils/fusefs-ntfs for R/W 406 | -- FAT/FAT32 407 | -- exFAT requires sysutils/fusefs-exfat 408 | -- EXT2 409 | -- EXT3 410 | -- EXT4 requires sysutils/fusefs-ext4fuse 411 | -- UFS 412 | 413 | It keeps state of the mounted devices at /var/run/automount.state and logs 414 | all activities to /var/log/automount.log file. 415 | 416 | The place for the script is at /usr/local/sbin/automount.sh executable. 417 | 418 | The only additional configuration it requires is to add these lines as 419 | /usr/local/etc/devd/automount_devd.conf file, which would allow it to work. 420 | 421 | Remember to restart /etc/rc.d/devd daemon after adding 422 | /usr/local/etc/devd/automount_devd.conf file. 423 | 424 | Have Fun ;) 425 | vermaden 426 | 427 | 428 | 429 | 430 | -------------------------------------------------------------------------------- /automount: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright (c) 2012-2020 Slawomir Wojciech Wojtczak 4 | # Copyright (c) 2019 Rozhuk Ivan 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that following conditions are met: 9 | # 1. Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # 2. Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS 'AS IS' AND ANY 16 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | PATH=${PATH}:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin 27 | 28 | __usage() { 29 | cat << EOF 30 | AUTOMOUNT is a devd(8) based automounter for FreeBSD. 31 | 32 | It supports following file systems: 33 | UFS/FAT/exFAT/NTFS/EXT2/EXT3/EXT4/MTP/HFS/ISO9660 34 | 35 | Add these to mount NTFS/exFAT/EXT4/HFS/XFS/MTP respectively: 36 | o sysutils/fusefs-ntfs 37 | o sysutils/fusefs-exfat 38 | o sysutils/fusefs-ext4fuse 39 | o sysutils/fusefs-hfsfuse 40 | o sysutils/fusefs-lkl 41 | o sysutils/fusefs-simple-mtpfs 42 | 43 | By default it mounts/unmounts all removable media but 44 | it is possible to set some additional options at the 45 | /usr/local/etc/automount.conf config file. 46 | 47 | Below is a list of possible options with description. 48 | 49 | MNT_PREFIX (set to /media by default) 50 | With this options You can alter the default root 51 | for mounting the removable media, for example to 52 | the /mnt directory. 53 | 54 | example: MNT_PREFIX='/media' 55 | 56 | MNT_GROUP (wheel by default) 57 | If set to some group name, the mount command will 58 | chown(1) the mount directory with the group. 59 | 60 | example: group='operator' 61 | 62 | MNT_MODE (set to 775 by default) 63 | Value for chmod on mount point. 64 | 65 | FAT_ENCODING (set to en_US.UTF-8 by default) 66 | Only used with FAT32 mounts, specifies which 67 | encoding to use at the mount. 68 | 69 | example: FAT_ENCODING='en_US.ISO8859-1' 70 | 71 | FAT_CODEPAGE (set to CP866 by default) 72 | Only used with FAT32 mounts, specifies which 73 | code page to use at the mount. 74 | 75 | example: FAT_CODEPAGE='cp437' 76 | 77 | ISO9660_CODEPAGE (set to UTF-8 by default) 78 | Only used with cd9660 mounts, specifies which 79 | code page to use at the mount. 80 | 81 | ATIME (set to NO by default) 82 | When set to NO it will mount filesystems with 83 | noatime option when possible. 84 | 85 | example: ATIME='YES' 86 | 87 | RETRY_COUNT (set to 3 by default) 88 | How many times try to get file system type or try to mount. 89 | 90 | example: RETRY_COUNT='1' 91 | 92 | RETRY_DELAY (set to 1 second by default) 93 | Delay beetwin retry attempt. 94 | 95 | example: RETRY_DELAY='2.5' 96 | 97 | USERUMOUNT (set to NO by default) 98 | When set to YES it will 'chmod +s /sbin/umount' 99 | which would allow an USER to unmount the file 100 | system with their selected file manager. 101 | 102 | example: USERUMOUNT='YES' 103 | 104 | NOTIFY (set to NO by default) 105 | Use 'notify-send' and 'libnotify' to show notifications 106 | of mounting and unmounting devices on the desktop. 107 | 108 | example: NOTIFY='YES' 109 | 110 | WALL (set to NO by default) 111 | Use wall(1) to show notifications of mounting and 112 | unmounting devices on terminals of logged in users. 113 | 114 | example: WALL='YES' 115 | 116 | FM ('exo-open --launch FileManager' by default) 117 | If set to file manager command, the mount will 118 | launch the specified command after successful 119 | mount. Works only if USER parameter is also set. 120 | 121 | example: FM='nautilus --browser --no-desktop' 122 | 123 | BLACKLIST (unset by default) 124 | The automount will ignore devices defined here. 125 | 126 | example: BLACKLIST='da0 da3s1a' 127 | 128 | USER (root by default) 129 | If set to some username, the mount command will 130 | chown(1) the mount directory with the user and 131 | its primary user group. If used with FM option 132 | allows to launch the specified file manager after 133 | a successful mount. 134 | 135 | example: USER="vermaden" 136 | 137 | EOF 138 | exit 0 139 | } 140 | 141 | # display version if needed 142 | if [ "${1}" = '--version' -o \ 143 | "${1}" = '-version' -o \ 144 | "${1}" = 'version' -o \ 145 | "${1}" = '-v' ] 146 | then 147 | echo 148 | echo " ___ /\ ___ " 149 | echo " __/ /_ / \ _\ \__ " 150 | echo " ____ _____/_ __/__ / _/\ ___ ___ ____ ______ __\__ _\ " 151 | echo " / \ / / // // \ /\_/ \ / / \ / \\\ \ \ / \\\ \ " 152 | echo " / / // / // // / // \\\ \ \ \\\ \ \\\ \ \\\ \ \\\ \_ " 153 | echo " \_____\\\____/ \__\\\____//__________\\\__\__\__\\\____/ \_____\\\__\__\\\___\ " 154 | echo 155 | echo "automount 1.7.4 2021/03/27" 156 | exit 0 157 | fi 158 | 159 | # display help if needed 160 | if [ "${1}" = "-h" -o \ 161 | "${1}" = "--h" -o \ 162 | "${1}" = "-help" -o \ 163 | "${1}" = "--help" -o \ 164 | "${#}" -eq "0" -o \ 165 | "${#}" -eq "1" ] 166 | then 167 | __usage 168 | fi 169 | 170 | # read configuration file 171 | if [ -f /usr/local/etc/automount.conf ] ; then 172 | . /usr/local/etc/automount.conf 173 | fi 174 | 175 | # default values for global variables 176 | : ${MNT_PREFIX='/media'} # mount prefix 177 | : ${MNT_GROUP='wheel'} # use WHEEL group for popup 178 | : ${MNT_MODE='775'} # mount point mode 179 | : ${FAT_ENCODING='en_US.UTF-8'} # US/Canada 180 | : ${FAT_CODEPAGE='cp437'} # US/Canada 181 | : ${ISO9660_CODEPAGE='UTF-8'} # UTF-8 182 | : ${ATIME='NO'} # when NO mount with noatime 183 | : ${RETRY_COUNT='3'} # retry count 184 | : ${RETRY_DELAY='1'} # retry delay time 185 | : ${USERUMOUNT='NO'} # when YES add suid bit to umount(8) 186 | : ${NOTIFY='NO'} # use notify-send(1) (devel/libnotify) 187 | : ${WALL='NO'} # use wall(1) 188 | : ${FM='exo-open --launch FileManager'} # which file manager to use 189 | : ${LOG_FILE='/var/log/automount.log'} # log file 190 | : ${LOG_DATEFMT='%Y-%m-%d %H:%M:%S'} # 2012-02-20 07:49:09 191 | : ${STATE="/var/run/automount.state"} # current state file 192 | : ${USER="root"} # which user to use for popup 193 | 194 | # init of main variables 195 | DEV="/dev/${1}" 196 | MNT="${MNT_PREFIX}/${1}" 197 | UID=$( id -u ${USER} ) 198 | GID=$( pw group show -n ${MNT_GROUP} | awk -F':' '{print $3}' ) 199 | if [ ${?} -ne 0 ] 200 | then 201 | __log "${MNT_GROUP}: invalid group" 202 | exit 1 203 | fi 204 | 205 | # process ${USERUMOUNT} option 206 | case ${USERUMOUNT} in 207 | ([Yy][Ee][Ss]) 208 | chmod u+s /sbin/umount 1> /dev/null 2>&1 # WHEEL group member 209 | chmod u+s /sbin/mount* 1> /dev/null 2>&1 # WHEEL group member 210 | sysctl -q vfs.usermount=1 1> /dev/null 2>&1 # allow user to mount 211 | ;; 212 | esac 213 | 214 | # read only filesystem types for __guess_fs_type() function 215 | readonly FS_TYPE_UNKNOWN=0 216 | readonly FS_TYPE_ISO9660=1 217 | readonly FS_TYPE_UFS=8 218 | readonly FS_TYPE_EXT2=9 219 | readonly FS_TYPE_EXT3=10 220 | readonly FS_TYPE_EXT4=11 221 | readonly FS_TYPE_XFS=12 222 | readonly FS_TYPE_HFS=13 223 | readonly FS_TYPE_FAT=32 224 | readonly FS_TYPE_EXFAT=33 225 | readonly FS_TYPE_NTFS=34 226 | readonly FS_TYPE_MTP=128 227 | 228 | # FUNCTION: guess filesystem type from device 229 | __guess_fs_type() { # 1=DEV 230 | # first time guess with file(1) tool 231 | unset FS_TYPE 232 | local FS_TYPE=$( file -r -b -L -s ${1} 2> /dev/null | sed -E 's/label:\ \".*\"//g' ) 233 | case ${FS_TYPE} in 234 | (*ISO\ 9660*) return ${FS_TYPE_ISO9660} ;; 235 | (*Unix\ Fast\ File*) return ${FS_TYPE_UFS} ;; 236 | (*ext2*) return ${FS_TYPE_EXT2} ;; 237 | (*ext3*) return ${FS_TYPE_EXT3} ;; 238 | (*ext4*) return ${FS_TYPE_EXT4} ;; 239 | (*SGI\ XFS*) return ${FS_TYPE_XFS} ;; 240 | (*Macintosh\ HFS*) return ${FS_TYPE_HFS} ;; 241 | esac 242 | # second time guess with file(1) tool with -k option 243 | # (do not stop at the first match and keep going) 244 | unset FS_TYPE 245 | local FS_TYPE=$( file -k -r -b -L -s ${1} 2> /dev/null | sed -E 's/label:\ \".*\"//g' ) 246 | case ${FS_TYPE} in 247 | (*Unix\ Fast\ File*) return ${FS_TYPE_UFS} ;; 248 | (*NTFS*) return ${FS_TYPE_NTFS} ;; 249 | (*FAT*|*MSDOS*) return ${FS_TYPE_FAT} ;; 250 | esac 251 | # try with fstyp(8) last (exFAT on UFS issue) 252 | unset FS_TYPE 253 | local FS_TYPE=$( fstyp ${1} 2> /dev/null ) 254 | case ${FS_TYPE} in 255 | (cd9660) return ${FS_TYPE_ISO9660} ;; 256 | (ufs) return ${FS_TYPE_UFS} ;; 257 | (ext2fs) return ${FS_TYPE_EXT2} ;; 258 | (msdosfs) return ${FS_TYPE_FAT} ;; 259 | (exfat) return ${FS_TYPE_EXFAT} ;; 260 | (ntfs) return ${FS_TYPE_NTFS} ;; 261 | esac 262 | # magic detection code with dd(8) 263 | unset FS_TYPE 264 | local FS_TYPE=$( dd if="${1}" conv=sync count=1 bs=1k 2> /dev/null | strings | head -1 ) 265 | case ${FS_TYPE} in 266 | (*EXFAT*) return ${FS_TYPE_EXFAT} ;; 267 | esac 268 | return ${FS_TYPE_UNKNOWN} 269 | } 270 | 271 | # FUNCTION: add state to the ${STATE} file 272 | __state_add() { # 1=DEV 2=PROVIDER 3=MNT 273 | if [ -f ${STATE} ] 274 | then 275 | if grep -E "${3}$" ${STATE} 1> /dev/null 2> /dev/null 276 | then 277 | __log "${1}: duplicated '${STATE}'" 278 | exit 0 279 | fi 280 | fi 281 | echo "${1} ${2} ${3}" >> ${STATE} 282 | if [ "${NOTIFY}" = YES ] 283 | then 284 | __show_message "Device '${1}' mounted on '${3}' directory." 285 | fi 286 | if [ "${WALL}" = YES ] 287 | then 288 | echo "automount: Device '${1}' mounted on '${3}' directory." | wall 289 | fi 290 | } 291 | 292 | # FUNCTION: remove state from the ${STATE} file 293 | __state_remove() { # 1=MNT 294 | if [ -f ${STATE} ] 295 | then 296 | # backslash the slashes ;) 297 | BSMNT=$( echo ${1} | sed 's/\//\\\//g' ) 298 | sed -i '' "/${BSMNT}\$/d" ${STATE} 299 | if [ "${NOTIFY}" = YES ] 300 | then 301 | __show_message "Device '${1}' unmounted from '${3}' directory." 302 | fi 303 | if [ "${WALL}" = YES ] 304 | then 305 | echo "automount: Device '${1}' unmounted from '${3}' directory." | wall 306 | fi 307 | fi 308 | } 309 | 310 | # FUNCTION: add message to the ${LOG_FILE} file 311 | __log() { # @=MESSAGE 312 | echo $( date +"${LOG_DATEFMT}" ) "${@}" >> "${LOG_FILE}" 313 | } 314 | 315 | # FUNCTION: remove temp mount dir from ${MNT_PREFIX} path (like /media/da0 dir) 316 | __remove_dir() { # 1=TARGET 317 | if [ "${REMOVEDIRS}" = YES ] 318 | then 319 | if [ -d "${1}" ] 320 | then 321 | find "${1}" -type d -empty -maxdepth 1 -exec rm -r {} '+' 2> /dev/null 322 | fi 323 | fi 324 | } 325 | 326 | # FUNCTION: display wall(1) and/or notify-send(1) message 327 | __show_message() { # 1=MESSAGE 328 | case ${WALL} in 329 | ([Yy][Ee][Ss]) 330 | echo "automount: ${1}" | wall 331 | ;; 332 | esac 333 | case ${NOTIFY} in 334 | ([Yy][Ee][Ss]) 335 | local __DISPLAY_IDS=$( ps aew | sed -n 's|.*DISPLAY=\([-_a-zA-Z0-9:.]*\).*|\1|p' | sort -u | tr '\n' ' ' ) 336 | for __DISPLAY_ID in ${__DISPLAY_IDS} 337 | do 338 | local __USER=$( ps aewj | grep "DISPLAY=${__DISPLAY_ID}" | awk '{print $1;}' | sort -u | tr -cd '[:print:]' ) 339 | if [ -z "${__USER}" ] 340 | then 341 | continue 342 | fi 343 | su -l "${__USER}" -c "env DISPLAY=${__DISPLAY_ID} notify-send automount '${1}' &" 1> /dev/null 2>&1 344 | done 345 | ;; 346 | esac 347 | } 348 | 349 | # FUNCTION: check if device or mountpoint not already mounted 350 | __check_already_mounted() { # 1=DEV 2=MNT 351 | local MOUNT=$( mount ) 352 | if echo "${MOUNT}" | grep -q "^${1} on " 353 | then 354 | local MOUNT_POINT=$( echo "${MOUNT}" | grep "^${1} on " | cut -d ' ' -f 3-255 | cut -d '(' -f 1 | sed s/.$// ) 355 | __log "${DEV}: already mounted on '${MOUNT_POINT}' mount point" 356 | exit 1 357 | fi 358 | if echo "${MOUNT}" | grep -q " on ${2} " 359 | then 360 | local DEVICE=$( echo "${MOUNT}" | grep " on ${2} " | awk '{print $1}' ) 361 | __log "${DEVICE}: already mounted on '${2}' mount point" 362 | exit 1 363 | fi 364 | } 365 | 366 | # FUNCTION: wait for device to appear (sometimes needed) 367 | __wait_for_device() { # 1=DEV 368 | # do not wait for MTP and CD-ROM devices 369 | case ${1} in 370 | (*ugen*|iso9660*) 371 | return 372 | ;; 373 | esac 374 | # try to read from device to ensure that it alive 375 | local COUNT=0 376 | while ! dd if="${1}" of=/dev/null conv=sync count=1 bs=8k 1> /dev/null 2>&1 377 | do 378 | if [ ! -e "${1}" ] 379 | then 380 | __log "${1}: device gone" 381 | exit 1 382 | fi 383 | COUNT=$(( ${COUNT} + 1 )) 384 | if [ ${COUNT} -ge ${RETRY_COUNT} ] 385 | then 386 | return 387 | fi 388 | sleep "${RETRY_DELAY}" 389 | __log "${1}: wait for device retry ${COUNT}/${RETRY_COUNT}" 390 | done 391 | } 392 | 393 | # FUNCTION: check if device is a block device 394 | __check_block_device() { # 1=DEV 395 | # first check if its block device 396 | if ! fstyp ${1} 1> /dev/null 2>&1 397 | then 398 | __log "${DEV}: not a block device" 399 | exit 0 400 | fi 401 | } 402 | 403 | # main ATTACH/DETACH block 404 | case ${2} in 405 | (attach) 406 | # check if device still exists 407 | if [ ! -e "${DEV}" ] 408 | then 409 | __log "${DEV}: device does not exists" 410 | exit 1 411 | fi 412 | __log "${DEV}: attach" 413 | # blacklist check 414 | if [ -n "${BLACKLIST}" ] 415 | then 416 | for I in ${BLACKLIST} 417 | do 418 | if [ "${1}" = "${I}" ] 419 | then 420 | __log "${DEV}: device blocked by BLACKLIST option" 421 | exit 0 422 | fi 423 | done 424 | fi 425 | # check is device already mounted 426 | __check_already_mounted "${DEV}" "${MNT}" 427 | # make sure that data can be read from device 428 | __wait_for_device "${DEV}" 429 | # detect filesysytem type 430 | case ${1} in 431 | (iso9660*) 432 | FS_TYPE=${FS_TYPE_ISO9660} 433 | ;; 434 | (ugen*) 435 | FS_TYPE=${FS_TYPE_MTP} 436 | ;; 437 | (cd*) 438 | __guess_fs_type "${DEV}" 439 | FS_TYPE=${?} 440 | ;; 441 | (da*|mmcsd*) 442 | __check_block_device "${DEV}" 443 | __guess_fs_type "${DEV}" 444 | FS_TYPE=${?} 445 | ;; 446 | esac 447 | # process ATIME option 448 | case ${ATIME} in 449 | ([Nn][Oo]) OPTS="-o noatime" ;; 450 | esac 451 | # filesystem options abstraction layer 452 | case ${FS_TYPE} in 453 | (${FS_TYPE_ISO9660}) 454 | FS_CHECK_CMD='' 455 | FS_CHECK_ARGS='' 456 | FS_MOUNT_CMD='mount' 457 | FS_MOUNT_ARGS="-t cd9660 -o -e,-C=${ISO9660_CODEPAGE} ${DEV} ${MNT}" 458 | ;; 459 | (${FS_TYPE_UFS}) 460 | FS_CHECK_CMD='fsck_ufs' 461 | FS_CHECK_ARGS="-C -y" 462 | FS_MOUNT_CMD='mount' 463 | FS_MOUNT_ARGS="-t ufs ${OPTS} ${DEV} ${MNT}" 464 | ;; 465 | (${FS_TYPE_EXT2}) 466 | FS_CHECK_PORT='sysutils/e2fsprogs' 467 | FS_CHECK_CMD='fsck.ext2' 468 | FS_CHECK_ARGS="-y" 469 | FS_MOUNT_CMD='mount' 470 | FS_MOUNT_ARGS="-t ext2fs ${OPTS} ${DEV} ${MNT}" 471 | ;; 472 | (${FS_TYPE_EXT3}) 473 | FS_CHECK_PORT='sysutils/e2fsprogs' 474 | FS_CHECK_CMD='fsck.ext3' 475 | FS_CHECK_ARGS="-y" 476 | FS_MOUNT_CMD='mount' 477 | FS_MOUNT_ARGS="-t ext2fs ${OPTS} ${DEV} ${MNT}" 478 | ;; 479 | (${FS_TYPE_EXT4}) 480 | FS_CHECK_PORT='sysutils/e2fsprogs' 481 | FS_CHECK_CMD='fsck.ext4' 482 | FS_CHECK_ARGS="-y" 483 | FS_MOUNT_PORT='sysutils/fusefs-lkl' 484 | FS_MOUNT_CMD='lklfuse' 485 | FS_MOUNT_ARGS="-o type=ext4 -o allow_other -o intr -o uid=${UID} -o gid=${GID} -o umask=002 ${DEV} ${MNT}" 486 | ;; 487 | (${FS_TYPE_XFS}) 488 | FS_CHECK_PORT='sysutils/xfsprogs' 489 | FS_CHECK_CMD='xfs_repair' 490 | FS_CHECK_ARGS="-d" 491 | FS_MOUNT_CMD='lklfuse' 492 | FS_MOUNT_ARGS="-o type=xfs -o allow_other -o uid=${UID} -o gid=${GID} ${DEV} ${MNT}" 493 | FS_MOUNT_PORT='sysutils/fusefs-lkl' 494 | ;; 495 | (${FS_TYPE_HFS}) 496 | FS_CHECK_CMD='' 497 | FS_CHECK_ARGS='' 498 | FS_MOUNT_CMD='hfsfuse' 499 | FS_MOUNT_ARGS="--force ${OPTS} ${DEV} ${MNT}" 500 | FS_MOUNT_PORT='sysutils/fusefs-hfsfuse' 501 | ;; 502 | (${FS_TYPE_FAT}) 503 | # FreeBSD 12.x does not support '-o large' option 504 | case $( sysctl -n kern.osrelease ) in 505 | (10*) LARGE="-o large" ;; 506 | (11*) LARGE="-o large" ;; 507 | (*) LARGE="" ;; 508 | esac 509 | FS_CHECK_CMD='fsck_msdosfs' 510 | FS_CHECK_ARGS="-C -y" 511 | FS_MOUNT_CMD='mount_msdosfs' 512 | FS_MOUNT_ARGS="-o longnames -m 755 -M ${MNT_MODE} -D ${FAT_CODEPAGE} -L ${FAT_ENCODING} -u ${UID} -g ${GID} ${OPTS} ${LARGE} ${DEV} ${MNT}" 513 | ;; 514 | (${FS_TYPE_EXFAT}) 515 | FS_CHECK_PORT='sysutils/exfat-utils' 516 | FS_CHECK_CMD='fsck.exfat' 517 | FS_CHECK_ARGS="-y" 518 | FS_MOUNT_CMD='mount.exfat' 519 | FS_MOUNT_UMASK=$( printf "%03o" $((~0775&0777)) ) 520 | FS_MOUNT_ARGS="-o uid=${UID} -o gid=${GID} -o umask=${FS_MOUNT_UMASK} ${OPTS} ${DEV} ${MNT}" 521 | FS_MOUNT_PORT='sysutils/fusefs-exfat' 522 | ;; 523 | (${FS_TYPE_NTFS}) 524 | FS_CHECK_CMD='' 525 | FS_CHECK_ARGS='' 526 | if /usr/bin/which -s ntfs-3g 527 | then 528 | FS_MOUNT_CMD='ntfs-3g' 529 | FS_MOUNT_ARGS="-o recover ${OPTS} ${DEV} ${MNT}" 530 | FS_MOUNT_PORT='sysutils/fusefs-ntfs' 531 | else 532 | FS_MOUNT_CMD='mount_ntfs' 533 | FS_MOUNT_ARGS="-u root -g ${MNT_GROUP} ${OPTS} ${DEV} ${MNT}" 534 | fi 535 | ;; 536 | (${FS_TYPE_MTP}) 537 | FS_PORT='sysutils/fusefs-simple-mtpfs' 538 | FS_CHECK_CMD='' 539 | FS_CHECK_ARGS='' 540 | FS_MOUNT_CMD='simple-mtpfs' 541 | if ! /usr/bin/which -s "${FS_MOUNT_CMD}" 542 | then 543 | __log "command '${FS_MOUNT_CMD}' not found" 544 | exit 1 545 | fi 546 | PHONEDEV=$( simple-mtpfs --list-devices -d ${DEV} 2> /dev/null ) 547 | if [ "${PHONEDEV}" = "No raw devices found." ] 548 | then 549 | __log "${DEV}: no raw devices found" 550 | exit 0 551 | fi 552 | PHONEDEV=$( echo "${PHONEDEV}" | awk '{print $1}' | tr -d ':' ) 553 | if [ ! ${PHONEDEV} ] 554 | then 555 | __log "${DEV}: no MTP devices found" 556 | exit 0 557 | fi 558 | FS_MOUNT_ARGS="--device ${PHONEDEV} ${MNT} -o allow_other -o uid=${UID} -o gid=${GID}" 559 | ;; 560 | (*) 561 | __log "${DEV}: filesystem not supported or no filesystem" 562 | exit 0 563 | ;; 564 | esac 565 | 566 | # create mount point 567 | mkdir -m "${MNT_MODE}" -p "${MNT}" 568 | __log "${DEV}: create '${MNT}' dir" 569 | 570 | # check file system before mount 571 | if [ -n "${FS_CHECK_CMD}" ] 572 | then 573 | if ! /usr/bin/which -s "${FS_CHECK_CMD}" 574 | then 575 | __log "command '${FS_CHECK_CMD}' not found" 576 | __log "please install '${FS_CHECK_PORT}' port or package" 577 | exit 1 578 | fi 579 | ${FS_CHECK_CMD} ${FS_CHECK_ARGS} ${DEV} \ 580 | | while read LINE 581 | do 582 | __log "${DEV}: ${FS_CHECK_CMD} ${LINE}" 583 | done 584 | fi 585 | 586 | # check is device already mounted 587 | __check_already_mounted "${DEV}" "${MNT}" 588 | 589 | # try to mount 590 | if ! /usr/bin/which -s "${FS_MOUNT_CMD}" 591 | then 592 | __log "command '${FS_MOUNT_CMD}' not found" 593 | __log "please install '${FS_MOUNT_PORT}' port or package" 594 | exit 1 595 | fi 596 | __wait_for_device "${DEV}" 597 | COUNT=0 598 | while ! ${FS_MOUNT_CMD} ${FS_MOUNT_ARGS} 2> /dev/null 599 | do 600 | if [ ! -e "${DEV}" ] 601 | then 602 | __log "${DEV}: device gone" 603 | exit 1 604 | fi 605 | COUNT=$(( ${COUNT} + 1 )) 606 | if [ ${COUNT} -gt ${RETRY_COUNT} ] 607 | then 608 | __log "${DEV}: mount FAIL: '${FS_MOUNT_CMD} ${FS_MOUNT_ARGS}'" 609 | exit 1 610 | fi 611 | sleep "${RETRY_DELAY}" 612 | __log "${DEV}: filesystem mount retry: ${COUNT}/${RETRY_COUNT}" 613 | done 614 | __log "${DEV}: mount OK: '${FS_MOUNT_CMD} ${FS_MOUNT_ARGS}'" 615 | 616 | # add needed rights 617 | chown "${USER}:${MNT_GROUP}" "${MNT}" 618 | __log "${DEV}: chown '${MNT}' dir with '${USER}:${MNT_GROUP}' rights" 619 | 620 | # add state 621 | PROVIDER=$( mount | grep -m 1 " ${MNT} " | awk '{printf $1}' ) 622 | __state_add ${DEV} ${PROVIDER} ${MNT} 623 | 624 | # open file manager and display message 625 | __show_message "Device '${DEV}' mounted on '${MNT}' directory." 626 | if [ -n "${FM}" ] 627 | then 628 | GROUP_USERS=$( pw group show ${MNT_GROUP} | sed -e 's|.*:||' -e 's|,| |g' ) 629 | for I in ${GROUP_USERS} 630 | do 631 | DISPLAY_ID=$( ps aew -U "${I}" | grep -v Xorg | sed -n 's|.*DISPLAY=\([-_a-zA-Z0-9:.]*\).*|\1|p' | sort -u | head -n 1 | tr -cd '[:print:]' ) 632 | if [ -z "${DISPLAY_ID}" ] 633 | then 634 | continue 635 | fi 636 | __log "${DEV}: starting '${FM}' file manager" 637 | su -l "${I}" -c "env DISPLAY=${DISPLAY_ID} ${FM} ${MNT} &" 1> /dev/null 2>&1 638 | done 639 | fi 640 | ;; 641 | 642 | (detach) 643 | __log "${DEV}: detach" 644 | if [ -f ${STATE} ] 645 | then 646 | grep -E "${MNT_PREFIX}/${1}$" ${STATE} \ 647 | | while read DEV PROVIDER MNT 648 | do 649 | TARGET=$( mount | grep -v \.gvfs | grep -m 1 -E "^${PROVIDER} " | awk '{print $3}' ) 650 | __state_remove ${MNT} 651 | if [ -z ${TARGET} ] 652 | then 653 | continue 654 | fi 655 | ( # put entire umount/find/rm block into background 656 | umount -f "${TARGET}" 1> /dev/null 2>&1 657 | __remove_dir "${TARGET}" 658 | __log "${DEV}: (state) umount '${TARGET}'" 659 | __log "${DEV}: (state) mount point '${TARGET}' removed" 660 | ) & 661 | unset TARGET 662 | done 663 | umount -f "${MNT_PREFIX}/${1}" 1> /dev/null 2>&1 664 | __log "${DEV}: (direct) umount '${MNT_PREFIX}/${1}'" 665 | __remove_dir "${MNT_PREFIX}/${1}" 666 | __log "${DEV}: (direct) mount point '${MNT_PREFIX}/${1}' removed" 667 | __show_message "Device '${DEV}' unmounted from '${MNT}' directory." 668 | fi 669 | ;; 670 | 671 | esac 672 | --------------------------------------------------------------------------------