diff --git a/afpcdev.c b/afpcdev.c index 1adc84c..ffb7175 100644 --- a/afpcdev.c +++ b/afpcdev.c @@ -109,6 +109,9 @@ SFReplyRec2 sfReplyRec; Word modifiers = 0; +char zoneBuf[ZONE_MAX + 1]; +char AFPOverTCPZone[] = "AFP over TCP"; + unsigned int flags = fLargeReads; /* for AFP over TCP connections */ void fillEasyMountRec(char *server, char *zone, char *volume, char *user, @@ -264,13 +267,24 @@ void finalizeURLParts(AFPURLParts *urlParts) } } + /* + * Assemble zone name for TCP, including any options. + * Note that the generated zone name can't be over 32 characters. + */ if (urlParts->protocol == proto_TCP) { - urlParts->zone = afpOptions[0].zoneString; - for (i = 0; afpOptions[i].zoneString != NULL; i++) { - if (afpOptions[i].flags == flags) { - urlParts->zone = afpOptions[i].zoneString; + strcpy(zoneBuf, AFPOverTCPZone); + if (flags != 0) { + strcat(zoneBuf, " ("); + + for (i = 0; afpOptions[i].optString != NULL; i++) { + if (afpOptions[i].flag & flags) { + strcat(zoneBuf, afpOptions[i].optString); + strcat(zoneBuf, ","); + } } + zoneBuf[strlen(zoneBuf) - 1] = ')'; } + urlParts->zone = zoneBuf; } } diff --git a/afpoptions.c b/afpoptions.c index fe809db..c132880 100644 --- a/afpoptions.c +++ b/afpoptions.c @@ -2,14 +2,15 @@ #include "afpoptions.h" +/* + * These are option codes that can be used in the zone string, e.g. + * "AFP over TCP (LR,22)". Note that the zone string is limited to 32 + * characters. With 2-character options, we can use up to six at once. + */ AFPOptions afpOptions[] = { - /*12345678901234567890123456789012 <- max length = 32 */ - {"AFP over TCP", 0}, - {"AFP over TCP (LargeReads)", fLargeReads}, - {"AFP over TCP (AFP2.2)", fForceAFP22}, - {"AFP over TCP (LargeReads,AFP2.2)", fLargeReads | fForceAFP22}, - {"AFP over TCP (AFP2.2,FakeSleep)", fForceAFP22 | fFakeSleep}, - {"AFP over TCP (LR,AFP2.2,FS)", fLargeReads | fForceAFP22 | fFakeSleep}, + {"LR", fLargeReads}, + {"22", fForceAFP22}, + {"FS", fFakeSleep}, {0, 0} }; diff --git a/afpoptions.h b/afpoptions.h index a289374..548bc17 100644 --- a/afpoptions.h +++ b/afpoptions.h @@ -6,8 +6,8 @@ #define fFakeSleep 0x0004 typedef struct AFPOptions { - char *zoneString; - unsigned int flags; + char *optString; + unsigned int flag; } AFPOptions; extern AFPOptions afpOptions[]; diff --git a/atipmapping.c b/atipmapping.c index 55f850b..2679fcb 100644 --- a/atipmapping.c +++ b/atipmapping.c @@ -1,6 +1,7 @@ #pragma noroot #include +#include #include #include #include @@ -20,6 +21,7 @@ struct ATIPMapping atipMapping; static char ATIPTypeName[] = "\pAFPServer"; static char DefaultZoneName[] = "\p*"; +static char AFPOverTCPZone[] = "AFP over TCP"; // Next numbers to use for new mappings static int nextNode = 1; @@ -36,8 +38,8 @@ static int nextSocket = 1; LongWord DoLookupName(NBPLookupNameRec *commandRec) { cvtRec hostInfo; dnrBuffer dnrInfo; - Byte *curr, *dest; - unsigned int count, nameLen; + Byte *curr, *dest, *sep; + unsigned int count, nameLen, i; NBPLUNameBufferRec *resultBuf; LongWord initialTime; Word stateReg; @@ -74,16 +76,49 @@ LongWord DoLookupName(NBPLookupNameRec *commandRec) { goto passThrough; *dest++ = ATIPTypeName[count]; } - nameLen = *curr; - flags = 0xFFFF; - for (count = 0; afpOptions[count].zoneString != NULL; count++) { - if (strncasecmp(afpOptions[count].zoneString, curr+1, nameLen) == 0) { - flags = afpOptions[count].flags; - break; + 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; } } - if (flags == 0xFFFF) - goto passThrough; nameLen = *DefaultZoneName; for (count = 0; count <= nameLen; count++) {