AFPBridge/afpcdev.c

242 lines
6.4 KiB
C

#pragma cdev cdevMain
#include <types.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <locator.h>
#include <gsos.h>
#include <orca.h>
#include <AppleTalk.h>
#include <quickdraw.h>
#include <window.h>
#include <control.h>
#include "afpurlparser.h"
#include "cdevutil.h"
#define MachineCDEV 1
#define BootCDEV 2
#define InitCDEV 4
#define CloseCDEV 5
#define EventsCDEV 6
#define CreateCDEV 7
#define AboutCDEV 8
#define RectCDEV 9
#define HitCDEV 10
#define RunCDEV 11
#define EditCDEV 12
#define serverAddressTxt 2
#define urlLine 3
#define saveAliasBtn 4
#define connectBtn 1
#define fstMissingError 3000
#define noEasyMountError 3001
FSTInfoRecGS fstInfoRec;
char urlBuf[257];
WindowPtr wPtr = NULL;
typedef struct EasyMountRec {
Word size;
char entity[97];
char volume[28];
char user[32];
char password[8];
char volpass[8];
/* Below fields are new in System 6.0.1 version */
Word version; /* 1 = file alias, 2 = 6.0.1-style server alias */
char volume2[29];
} EasyMountRec;
EasyMountRec easyMountRec;
struct ResultRec {
Word recvCount;
Word result;
} resultRec;
char afpOverTCPZone[] = "AFP over TCP";
void fillEasyMountRec(char *server, char *zone, char *volume, char *user,
char *password, char *volpass)
{
unsigned int i;
char *next;
memset(&easyMountRec, 0, sizeof(easyMountRec));
easyMountRec.size = offsetof(EasyMountRec, volume2) + 2 + strlen(volume);
easyMountRec.version = 2;
i = 0;
next = server;
easyMountRec.entity[i++] = strlen(next);
while (*next != 0 && i < sizeof(easyMountRec.entity) - 2) {
easyMountRec.entity[i++] = *next++;
}
next = "AFPServer";
easyMountRec.entity[i++] = strlen(next);
while (*next != 0 && i < sizeof(easyMountRec.entity) - 1) {
easyMountRec.entity[i++] = *next++;
}
next = zone;
easyMountRec.entity[i++] = strlen(next);
while (*next != 0 && i < sizeof(easyMountRec.entity)) {
easyMountRec.entity[i++] = *next++;
}
easyMountRec.volume[0] = strlen(volume);
strncpy(&easyMountRec.volume[1], volume, sizeof(easyMountRec.volume) - 1);
easyMountRec.user[0] = strlen(user);
strncpy(&easyMountRec.user[1], user, sizeof(easyMountRec.user) - 1);
strncpy(&easyMountRec.password[0], password, sizeof(easyMountRec.password));
strncpy(&easyMountRec.volpass[0], volpass, sizeof(easyMountRec.volpass));
easyMountRec.volume2[0] = strlen(volume) + 1;
easyMountRec.volume2[1] = ':';
strncpy(&easyMountRec.volume2[2], volume, sizeof(easyMountRec.volume2) - 2);
}
Word tryConnect(enum protocol protocol, AFPURLParts *urlParts)
{
resultRec.recvCount = 0;
resultRec.result = 0;
if (protocol == proto_AT) {
fillEasyMountRec(urlParts->server, urlParts->zone,
urlParts->volume, urlParts->username,
urlParts->password, urlParts->volpass);
} else if (protocol == proto_TCP) {
fillEasyMountRec(urlParts->server, afpOverTCPZone,
urlParts->volume, urlParts->username,
urlParts->password, urlParts->volpass);
} else {
return atInvalidCmdErr;
}
SendRequest(0x8000, sendToName+stopAfterOne, (Long)"\pApple~EasyMount~",
(Long)&easyMountRec, (Ptr)&resultRec);
if (resultRec.recvCount == 0) {
return atInvalidCmdErr;
} else {
return resultRec.result;
}
}
void connect(AFPURLParts *urlParts)
{
Word result;
if (urlParts->protocol == proto_AT || urlParts->protocol == proto_TCP) {
result = tryConnect(urlParts->protocol, urlParts);
} else if (urlParts->protocol == proto_unknown) {
/*
* If server name contains a dot it's probably an IP address or
* domain name, so try TCP first. Otherwise try AppleTalk first.
* In either case, we proceed to try the other if we get an NBP error.
*/
if (strchr(urlParts->server, '.') != NULL) {
if (((result = tryConnect(proto_TCP, urlParts)) & 0xFF00) == 0x0400)
result = tryConnect(proto_AT, urlParts);
} else {
if (((result = tryConnect(proto_AT, urlParts)) & 0xFF00) == 0x0400)
result = tryConnect(proto_TCP, urlParts);
}
} else {
AlertWindow(awResource, NULL, protoInvalidError);
return;
}
if (resultRec.recvCount == 0) {
AlertWindow(awResource, NULL, noEasyMountError);
return;
}
}
void finalizeURLParts(AFPURLParts *urlParts)
{
if (urlParts->server == NULL)
urlParts->server = "";
if (urlParts->zone == NULL)
urlParts->zone = "*";
if (urlParts->username == NULL)
urlParts->username = "";
if (urlParts->password == NULL)
urlParts->password = "";
if (urlParts->auth == NULL)
urlParts->auth = "";
if (urlParts->volpass == NULL)
urlParts->volpass = "";
if (urlParts->volume == NULL)
urlParts->volume = "";
}
void DoConnect(char *url)
{
AFPURLParts urlParts;
int validationError;
urlParts = parseAFPURL(url);
if (validationError = validateAFPURL(&urlParts)) {
AlertWindow(awResource, NULL, validationError);
return;
}
finalizeURLParts(&urlParts);
connect(&urlParts);
}
void DoHit(long ctlID)
{
if (ctlID == connectBtn) {
GetLETextByID(wPtr, urlLine, (StringPtr)&urlBuf);
DoConnect(urlBuf+1);
} else if (ctlID == saveAliasBtn) {
}
}
long DoMachine(void)
{
unsigned int i;
/* Check for presence of AppleShare FST. */
fstInfoRec.pCount = 2;
fstInfoRec.fileSysID = 0;
for (i = 1; fstInfoRec.fileSysID != appleShareFSID; i++) {
fstInfoRec.fstNum = i;
GetFSTInfoGS(&fstInfoRec);
if (toolerror() == paramRangeErr) {
InitCursor();
AlertWindow(awResource, NULL, fstMissingError);
return 0;
}
}
return 1;
}
LongWord cdevMain (LongWord data2, LongWord data1, Word message)
{
long result = 0;
switch(message) {
case MachineCDEV: result = DoMachine(); break;
case HitCDEV: DoHit(data2); break;
case InitCDEV: wPtr = (WindowPtr)data1; break;
case CloseCDEV: wPtr = NULL; break;
}
ret:
FreeAllCDevMem();
return result;
}