mount_webdav authentication

pudge on 2002-11-06T15:07:16

Yesterday I was talking to some guys who had set up a WebDAV server, but noted that under Mac OS X, the keychain was not remembering the authentication for it. Sucks. So I played around with mount/mount_webdav and got it to work.

But man, is it ugly. mount_webdav requires you to write out a file with the username and password in it, then pass the file descriptor to the program as an argument. So I encode the username and password, then make a temp file and unlink it, prepare the file with select() and fcntl(), then print to it and call mount with the appropriate arguments.

And then, it seems Mac OS X's open command won't open the new volume most of the time. I also tried AppleScript, with open location, and that similarly failed. Bug.

#!/usr/bin/perl -w use strict; use File::Temp 'tempfile'; use Fcntl 'F_SETFD';

my $server = 'dav.example.com'; my $path = '/Volumes/dav'; my $user = 'login'; my $pass = 'password';

# encode username and password (my $ulen = sprintf "%4s", chr length $user) =~ s/ /\0/g; (my $plen = sprintf "%4s", chr length $pass) =~ s/ /\0/g; my $data = sprintf "%s%s%s%s", $ulen, $user, $plen, $pass;

# create mount point and temp file, and unlink file so no one can see it mkdir $path; my $fh = tempfile(); unlink $fh;

# autoflush select( (select($fh), $|++)[0] );

# get ready to pass fd my $fd = fileno($fh); fcntl($fh, F_SETFD, 0) or die "Can't clear close-on-exec flag on temp fh: $!\n";

# finally, write username and password and mount print $fh $data; system('mount', '-t', 'webdav', '-o', "-a$fd", $server, $path);

# open (first usually fails, don't know why; but you can just open the # icon in the Volumes folder, which is just as good as opening the icon # on the Desktop system('open', $path); system('open', '/Volumes/');

# clean up close $fh;

__END__

Now Playing: What It Takes - Aerosmith (Pump)


Pipes, not files

Dom2 on 2002-11-06T16:55:06

Shouldn't you be able to use a pipe instead of a file there:
my $pid = open(FH, "-|");
if ($pid) {
    print FH $authinfo, "\0";
} else {
    #child.
    exec 'mount_webdav', '-a0', 'other', 'args';
}

That's not right, but the basic idea is well explained in perlipc under "Safe Pipe Opens". Hope this helps.

Hmmm, I notice you can also do this under 5.8:

open FH, "-|", 'mount_webdav', '-a0', 'arg'
    or die "open(mount_webdav|): $!";

-Dom