Mounty for OSX

Mounty in Action Asking for Password

A few years ago I was looking for a way to automatically mount a server share on my MacBook when I was connected to my home WiFi. In fact I had several shares at home and at my office, that I used on regular basis, and I didn’t want to always have to manually reconnect to them. After some research, I found a tool in the AppStore that claimed to do just this, but I wanted something that could work in CLI and could be scriptable. Thus Mounty was borne.

About Mounty

Mounty is a tool for mounting remote shares on OSX. It takes WiFi SSID as an argument, and attempts the connection only if the SSID matches the network the system is currently connected to. It also verifies that the share isn’t already mounted. If it is, it returns the location where the share is already mounted, rather then attempting to mount it again.

Mounty is superior to the unix mount command available in OSX because it can store the credentials for the network share (username and password) in the keychain. This makes it ideal for use in bash scripts. For instance, you can make a bash script that calls mounty several times, iterating through all kinds of network shares you connect to on regular basis. Simply add that script to cron, and you’ll never have to worry about manually remounting those shares again.

I added the SSID argument so that monty knows to only attempt the connection if the system is connected to the right network, ideal for laptops, if you work in several different locations, and need to access different network shares, based on the location.

Installing Mounty

You can find a copy of Mounty on GitHub. Just grab the source and compile it in Xcode, or download the latest compiled binary. To install simply copy it to your computer, for instance to /usr/bin/.

Using Mounty

Run it in the terminal like this:

mounty smb://server/share /mount/pint WiFi_SSID

It works with any type of share that OSX can mount, not just samba, as it relies on the internal NetFS library. The first time you connect to a password protected share, a GUI popup dialog will ask you for the password. After the first time, the password will be safely saved in the Keychain and you will not be bugged again. This means you can use Mounty in BASH scripts without the need to also include your password in the script.

Final Thoughts

Hope you like Mounty. Use it, love it, fork it, make changes, send pull requests. Enjoy!

Released under MIT License.

Source Code

#import <Foundation/Foundation.h>
#import <NetFS/NetFS.h>
#import <CoreWLAN/CoreWLAN.h>

int main (int argc, const char * argv[])
{
  @autoreleasepool {
    if(argc>=4){
      NSArray *arguments = [[NSProcessInfo processInfo] arguments];
      //NSLog(@"%@", arguments);
      NSString * share = arguments[1];
      NSString * path = arguments[2];
      NSString * ssid = arguments[3];
      
      
      // Check if connected to right SSID
      CWInterface *wif = [CWInterface interface];
      //NSString *wifissid = wif.ssid;
      if (![wif.ssid isEqualToString:ssid]) {
        printf("You are NOT connected to the right WiFi Base Station\n");
        return 0;
      }
      
      // Check if the Share is allready Mounted
      NSArray * keys = [NSArray arrayWithObjects:NSURLVolumeURLForRemountingKey, nil];
      NSArray * mountPaths = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:keys options:0];
      
      NSError * error;
      NSURL * remount;
      
      for (NSURL * mountPath in mountPaths) {
        [mountPath getResourceValue:&remount forKey:NSURLVolumeURLForRemountingKey error:&error];
        if(remount){
          if ([[[NSURL URLWithString:share] host] isEqualToString:[remount host]] && [[[NSURL URLWithString:share] path] isEqualToString:[remount path]]) {
            printf("Already mounted at %s\n", [[mountPath path] UTF8String]);
            return 0;
          }
        }
      }
      
      // Check if the Folder Exists
      NSFileManager *fileManager = [[NSFileManager alloc] init];
      BOOL isDir;
      if (![fileManager fileExistsAtPath:path isDirectory:&isDir] && !isDir) {
        printf("Mount Point deos NOT Exist. Please specify a valid mount point.\n");
        return 0;
      }
      
      CFMutableDictionaryRef mount_options = CFDictionaryCreateMutable( NULL, 0, NULL, NULL);
      CFDictionarySetValue(mount_options, kNetFSSoftMountKey, kCFBooleanTrue);
      CFDictionarySetValue(mount_options, kNetFSMountAtMountDirKey, kCFBooleanTrue);
      CFArrayRef mountpoints = NULL;
      
      OSStatus err = NetFSMountURLSync(
                       (__bridge CFURLRef) [NSURL URLWithString: share],    // URL to mount, e.g. nfs://server/path
                       (__bridge CFURLRef) [NSURL URLWithString: path], // Path for the mountpoint
                       NULL,                       // Auth user name (overrides URL)
                       NULL,                       // Auth password (overrides URL)
                       NULL,                       // Options for session open (see below)
                       mount_options,                  // Options for mounting (see below)
                       &mountpoints);                  // Array of mountpoints
      
      if(err != noErr)
        printf("Problems mounting the drive! Error %d", (int)err);
    }else{
      printf("Too few arguments. Expected: mounty smb://server/share /mount/pint WiFi_SSID\n");
    }
    return 0;
  }
}
Foldy Quad 2.0      HyperJump - A Quicker Way to CD


Comments