The following C program should be compiled with the Security framework as follows:
cc -framework Security -o mountwrapper mountwrapper.c
This program works only under Leopard, and requires that you have an AFP Internet password in your keychain with the exact hostname, username, and port number you specify on the command line. It does not look for approximate or ambiguous matches.
#include <unistd.h>
#include <stdio.h>
#include <Security/SecKeychain.h>
#include <stdlib.h>
#include <string.h>
extern char **environ;
int main(int argc, char **argv)
{
UInt32 passwordLength = 0;
void *passwordData;
OSStatus keychainStatus = 0;
UInt16 serverPort = 0;
if(argc < 6)
{
fprintf(stderr, "Usage: mountwrapper <hostname> <username> <share> <port> <mountpoint>\n");
return 1;
}
sscanf(argv[4], "%hu", &serverPort);
keychainStatus = SecKeychainFindInternetPassword(0, strlen(argv[1]), argv[1], 0, 0, strlen(argv[2]), argv[2], strlen(argv[3]), argv[3], serverPort, kSecProtocolTypeAFP, kSecAuthenticationTypeDefault, &passwordLength, &passwordData, 0);
if(keychainStatus || !passwordLength)
{
fprintf(stderr, "Keychain error: %i\n", keychainStatus);
return 1;
}
int pipein = 0, pipeout = 0, forkValue;
{
int myPipes1[2], myPipes2[2];
pipe(myPipes1);
pipe(myPipes2);
forkValue = fork();
if(forkValue)
{
pipein=myPipes1[0];
pipeout=myPipes2[1];
close(myPipes2[0]);
close(myPipes1[1]);
}
else
{
pipein = myPipes2[0];
pipeout = myPipes1[1];
close(myPipes1[0]);
close(myPipes2[1]);
}
}
if(!forkValue)
{
setsid();
int URLLength;
char *URL = malloc((URLLength = strlen(argv[1]) + strlen(argv[2]) + strlen(argv[3]) + strlen(argv[4]) + 12) + 1);
char *newArgv[] = {"mount_afp", "-i", "-o", "nobrowse", URL, argv[5], 0};
char *newEnv[] = {0};
snprintf(URL, URLLength, "afp://%s@%s:%hu%s", argv[2], argv[1], serverPort, argv[3]);
while(pipein < 3)
{
int oldpipein;
pipein = dup2(oldpipein = pipein, 8);
close(oldpipein);
}
while(pipeout < 3)
{
int oldpipeout;
pipein = dup2(oldpipeout = pipeout, 9);
close(oldpipeout);
}
dup2(pipein, 0);
dup2(pipeout, 1);
dup2(pipeout, 2);
execve("/sbin/mount_afp", newArgv, environ);
}
else
{
char buffer\[1024\];
int returnParams = 0;
write(pipeout, passwordData, passwordLength);
write(pipeout, "\n", 1);
size_t bytesRead = read(pipein, buffer, 1024);
size_t bufferOffset = 0;
if(bytesRead > 10)
if(!strncmp(buffer, "Password:", 9))
bufferOffset += 11;
fwrite(buffer + bufferOffset, 1, bytesRead, stderr);
wait(&returnParams);
}
return 0;
}