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