2017-03-18 23:44:11 +00:00
|
|
|
#pragma noroot
|
|
|
|
|
2017-04-09 04:40:41 +00:00
|
|
|
#include <stddef.h>
|
2017-04-22 20:39:02 +00:00
|
|
|
#include <string.h>
|
2017-04-09 04:40:41 +00:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <appletalk.h>
|
|
|
|
#include <tcpip.h>
|
|
|
|
#include <orca.h>
|
|
|
|
#include <misctool.h>
|
2017-04-02 05:55:27 +00:00
|
|
|
#include "atipmapping.h"
|
2017-04-09 04:40:41 +00:00
|
|
|
#include "asmglue.h"
|
|
|
|
#include "aspinterface.h"
|
2017-04-10 01:56:19 +00:00
|
|
|
#include "installcmds.h"
|
2017-04-10 04:02:00 +00:00
|
|
|
#include "cmdproc.h"
|
2017-04-15 03:16:55 +00:00
|
|
|
#include "afpoptions.h"
|
|
|
|
#include "strncasecmp.h"
|
2017-04-02 05:55:27 +00:00
|
|
|
|
2017-03-18 23:44:11 +00:00
|
|
|
struct ATIPMapping atipMapping;
|
2017-04-09 04:40:41 +00:00
|
|
|
|
|
|
|
#define DEFAULT_DSI_PORT 548
|
|
|
|
|
|
|
|
static char ATIPTypeName[] = "\pAFPServer";
|
2017-04-15 03:16:55 +00:00
|
|
|
static char DefaultZoneName[] = "\p*";
|
2017-04-22 20:39:02 +00:00
|
|
|
static char AFPOverTCPZone[] = "AFP over TCP";
|
2017-04-09 04:40:41 +00:00
|
|
|
|
|
|
|
// Next numbers to use for new mappings
|
|
|
|
static int nextNode = 1;
|
|
|
|
static int nextSocket = 1;
|
|
|
|
|
|
|
|
#define return_error(x) do { \
|
|
|
|
commandRec->result = (x); \
|
|
|
|
commandRec->actualMatch = 0; \
|
|
|
|
RestoreStateReg(stateReg); \
|
2017-04-10 01:56:19 +00:00
|
|
|
return 0; \
|
2017-04-09 04:40:41 +00:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#pragma databank 1
|
2017-04-10 01:56:19 +00:00
|
|
|
LongWord DoLookupName(NBPLookupNameRec *commandRec) {
|
2017-04-09 04:40:41 +00:00
|
|
|
cvtRec hostInfo;
|
|
|
|
dnrBuffer dnrInfo;
|
2017-04-22 20:39:02 +00:00
|
|
|
Byte *curr, *dest, *sep;
|
|
|
|
unsigned int count, nameLen, i;
|
2017-04-09 04:40:41 +00:00
|
|
|
NBPLUNameBufferRec *resultBuf;
|
|
|
|
LongWord initialTime;
|
|
|
|
Word stateReg;
|
2017-04-15 03:16:55 +00:00
|
|
|
unsigned int flags;
|
2017-04-09 04:40:41 +00:00
|
|
|
|
|
|
|
stateReg = ForceRomIn();
|
|
|
|
|
2017-04-16 23:25:58 +00:00
|
|
|
if (OS_KIND != KIND_GSOS)
|
|
|
|
goto passThrough;
|
|
|
|
|
2017-04-09 04:40:41 +00:00
|
|
|
// Length needed for result, assuming the request is for our type/zone
|
|
|
|
count = offsetof(NBPLUNameBufferRec, entityName)
|
2017-04-15 03:16:55 +00:00
|
|
|
+ ((EntName*)commandRec->entityPtr)->buffer[0] + 1
|
|
|
|
+ ATIPTypeName[0] + 1 + DefaultZoneName[0] + 1;
|
2017-04-09 04:40:41 +00:00
|
|
|
if (count > commandRec->bufferLength)
|
2017-04-15 03:16:55 +00:00
|
|
|
goto passThrough;
|
2017-04-09 04:40:41 +00:00
|
|
|
|
|
|
|
resultBuf = (NBPLUNameBufferRec *)commandRec->bufferPtr;
|
|
|
|
|
|
|
|
curr = &((EntName*)commandRec->entityPtr)->buffer[0];
|
|
|
|
dest = &resultBuf->entityName.buffer[0];
|
|
|
|
|
|
|
|
// Copy object name into result buffer
|
|
|
|
nameLen = *curr;
|
|
|
|
for (count = 0; count <= nameLen; count++) {
|
|
|
|
*dest++ = *curr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that entity type and zone are what we want,
|
|
|
|
// and copy names to result buffer.
|
|
|
|
nameLen = *curr;
|
|
|
|
for (count = 0; count <= nameLen; count++) {
|
|
|
|
if (toupper(*curr++) != toupper(ATIPTypeName[count]))
|
|
|
|
goto passThrough;
|
|
|
|
*dest++ = ATIPTypeName[count];
|
|
|
|
}
|
2017-04-22 20:39:02 +00:00
|
|
|
nameLen = *curr++;
|
|
|
|
|
|
|
|
/* Check if zone starts with "AFP over TCP" */
|
|
|
|
if (nameLen < sizeof(AFPOverTCPZone) - 1)
|
|
|
|
goto passThrough;
|
|
|
|
if (strncasecmp(AFPOverTCPZone, curr, sizeof(AFPOverTCPZone) - 1) != 0)
|
|
|
|
goto passThrough;
|
|
|
|
|
|
|
|
/* Check for options (in parentheses after "AFP over TCP ") */
|
|
|
|
flags = 0;
|
|
|
|
if (nameLen > sizeof(AFPOverTCPZone) - 1) {
|
|
|
|
nameLen -= sizeof(AFPOverTCPZone) - 1;
|
|
|
|
curr += sizeof(AFPOverTCPZone) - 1;
|
|
|
|
if (nameLen < 3)
|
|
|
|
goto passThrough;
|
|
|
|
if (curr[0] != ' ' || curr[1] != '(' || curr[nameLen-1] != ')')
|
|
|
|
goto passThrough;
|
|
|
|
nameLen -= 2;
|
|
|
|
curr += 2;
|
|
|
|
|
|
|
|
while (nameLen > 1) {
|
|
|
|
/* Parse options */
|
|
|
|
if (memchr(curr, '\0', nameLen - 1) != NULL)
|
|
|
|
goto passThrough;
|
|
|
|
sep = memchr(curr, ',', nameLen - 1);
|
|
|
|
count = (sep == NULL) ? nameLen - 1 : sep - curr;
|
|
|
|
|
|
|
|
for (i = 0; afpOptions[i].optString != NULL; i++) {
|
|
|
|
if (strncasecmp(curr, afpOptions[i].optString, count) == 0
|
|
|
|
&& afpOptions[i].optString[count] == '\0')
|
|
|
|
{
|
|
|
|
flags |= afpOptions[i].flag;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Don't accept unknown options */
|
|
|
|
if (afpOptions[i].optString == NULL)
|
|
|
|
goto passThrough;
|
|
|
|
|
|
|
|
nameLen -= count + 1;
|
|
|
|
curr += count + 1;
|
2017-04-15 03:16:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nameLen = *DefaultZoneName;
|
2017-04-09 04:40:41 +00:00
|
|
|
for (count = 0; count <= nameLen; count++) {
|
2017-04-15 03:16:55 +00:00
|
|
|
*dest++ = DefaultZoneName[count];
|
2017-04-09 04:40:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (TCPIPValidateIPString(&resultBuf->entityName.buffer[0])) {
|
|
|
|
TCPIPConvertIPToHex(&hostInfo, &resultBuf->entityName.buffer[0]);
|
|
|
|
resultBuf->enumerator = 0;
|
|
|
|
|
|
|
|
// TCPIPConvertIPToHex seems not to give port, so get it this way
|
|
|
|
hostInfo.cvtPort =
|
|
|
|
TCPIPMangleDomainName(0, &resultBuf->entityName.buffer[0]);
|
|
|
|
} else {
|
2017-04-18 23:05:00 +00:00
|
|
|
// Make sure we're connected before doing DNS lookup.
|
|
|
|
if (TCPIPGetConnectStatus() == FALSE)
|
|
|
|
TCPIPConnect(NULL);
|
|
|
|
|
2017-04-09 04:40:41 +00:00
|
|
|
hostInfo.cvtPort =
|
|
|
|
TCPIPMangleDomainName(0xE000, &resultBuf->entityName.buffer[0]);
|
|
|
|
TCPIPDNRNameToIP(&resultBuf->entityName.buffer[0], &dnrInfo);
|
|
|
|
if (toolerror())
|
|
|
|
return_error(nbpNameErr);
|
|
|
|
|
|
|
|
initialTime = GetTick();
|
|
|
|
while (dnrInfo.DNRstatus == DNR_Pending) {
|
|
|
|
if (GetTick() - initialTime >= 15*60)
|
|
|
|
break;
|
|
|
|
TCPIPPoll();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Re-copy object name into result buffer to undo mangling
|
|
|
|
curr = &((EntName*)commandRec->entityPtr)->buffer[0];
|
|
|
|
dest = &resultBuf->entityName.buffer[0];
|
|
|
|
nameLen = *curr;
|
|
|
|
for (count = 0; count <= nameLen; count++) {
|
|
|
|
*dest++ = *curr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dnrInfo.DNRstatus == DNR_OK) {
|
|
|
|
hostInfo.cvtIPAddress = dnrInfo.DNRIPaddress;
|
|
|
|
resultBuf->enumerator = 1;
|
|
|
|
} else if (dnrInfo.DNRstatus == DNR_NoDNSEntry) {
|
|
|
|
return_error(0); // not really an error, but 0 results
|
|
|
|
} else {
|
|
|
|
TCPIPCancelDNR(&dnrInfo);
|
|
|
|
return_error(nbpNameErr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hostInfo.cvtPort == 0)
|
|
|
|
hostInfo.cvtPort = DEFAULT_DSI_PORT;
|
|
|
|
|
|
|
|
for (count = 0; count < MAX_SESSIONS; count++) {
|
|
|
|
if (sessionTbl[count].atipMapping.ipAddr == hostInfo.cvtIPAddress
|
|
|
|
&& sessionTbl[count].atipMapping.port == hostInfo.cvtPort)
|
|
|
|
{
|
|
|
|
atipMapping = sessionTbl[count].atipMapping;
|
|
|
|
goto haveMapping;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
atipMapping.ipAddr = hostInfo.cvtIPAddress;
|
|
|
|
atipMapping.port = hostInfo.cvtPort;
|
|
|
|
atipMapping.networkNumber = 0xFFFF; /* invalid/reserved */
|
|
|
|
atipMapping.node = nextNode++;
|
|
|
|
atipMapping.socket = nextSocket++;
|
|
|
|
if (nextNode == 254)
|
|
|
|
nextNode = 1;
|
|
|
|
if (nextSocket == 255)
|
|
|
|
nextSocket = 1;
|
|
|
|
|
|
|
|
haveMapping:
|
2017-04-15 03:16:55 +00:00
|
|
|
atipMapping.flags = flags;
|
2017-04-09 04:40:41 +00:00
|
|
|
resultBuf->netNum = atipMapping.networkNumber;
|
|
|
|
resultBuf->nodeNum = atipMapping.node;
|
|
|
|
resultBuf->socketNum = atipMapping.socket;
|
|
|
|
commandRec->actualMatch = 1;
|
|
|
|
commandRec->result = 0;
|
2017-04-10 04:02:00 +00:00
|
|
|
if ((commandRec->async & AT_ASYNC) && commandRec->completionPtr != 0) {
|
|
|
|
CallCompletionRoutine((void *)commandRec->completionPtr);
|
|
|
|
}
|
2017-04-09 04:40:41 +00:00
|
|
|
RestoreStateReg(stateReg);
|
2017-04-10 01:56:19 +00:00
|
|
|
return 0;
|
2017-04-09 04:40:41 +00:00
|
|
|
|
|
|
|
passThrough:
|
2017-04-10 01:56:19 +00:00
|
|
|
RestoreStateReg(stateReg);
|
|
|
|
return oldCmds[commandRec->command];
|
2017-04-09 04:40:41 +00:00
|
|
|
}
|
|
|
|
#pragma databank 0
|
|
|
|
|
|
|
|
#undef return_error
|