Complete basic implementation of AFP Mounter CDev.
It now invokes EasyMount by creating a temporary alias file. Support for saving the alias is also implemented.
This commit is contained in:
parent
73399e8eda
commit
91c2707cf3
367
afpcdev.c
367
afpcdev.c
|
@ -5,12 +5,17 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <locator.h>
|
#include <locator.h>
|
||||||
|
#include <misctool.h>
|
||||||
#include <gsos.h>
|
#include <gsos.h>
|
||||||
#include <orca.h>
|
#include <orca.h>
|
||||||
#include <AppleTalk.h>
|
#include <AppleTalk.h>
|
||||||
#include <quickdraw.h>
|
#include <quickdraw.h>
|
||||||
#include <window.h>
|
#include <window.h>
|
||||||
#include <control.h>
|
#include <control.h>
|
||||||
|
#include <resources.h>
|
||||||
|
#include <stdfile.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <finder.h>
|
||||||
#include "afpurlparser.h"
|
#include "afpurlparser.h"
|
||||||
#include "cdevutil.h"
|
#include "cdevutil.h"
|
||||||
|
|
||||||
|
@ -31,8 +36,17 @@
|
||||||
#define saveAliasBtn 4
|
#define saveAliasBtn 4
|
||||||
#define connectBtn 1
|
#define connectBtn 1
|
||||||
|
|
||||||
|
#define saveFilePrompt 100
|
||||||
|
|
||||||
#define fstMissingError 3000
|
#define fstMissingError 3000
|
||||||
#define noEasyMountError 3001
|
#define noEasyMountError 3001
|
||||||
|
#define tempFileError 3002
|
||||||
|
#define aliasFileError 3003
|
||||||
|
#define tempFileNameError 3004
|
||||||
|
#define saveAliasError 3005
|
||||||
|
|
||||||
|
#define EM_filetype 0xE2
|
||||||
|
#define EM_auxtype 0xFFFF
|
||||||
|
|
||||||
FSTInfoRecGS fstInfoRec;
|
FSTInfoRecGS fstInfoRec;
|
||||||
|
|
||||||
|
@ -40,27 +54,47 @@ char urlBuf[257];
|
||||||
|
|
||||||
WindowPtr wPtr = NULL;
|
WindowPtr wPtr = NULL;
|
||||||
|
|
||||||
|
/* System 6.0-style EasyMount rec, as documented in its FTN. */
|
||||||
typedef struct EasyMountRec {
|
typedef struct EasyMountRec {
|
||||||
Word size;
|
|
||||||
char entity[97];
|
char entity[97];
|
||||||
char volume[28];
|
char volume[28];
|
||||||
char user[32];
|
char user[32];
|
||||||
char password[8];
|
char password[8];
|
||||||
char volpass[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 easyMountRec;
|
EasyMountRec easyMountRec;
|
||||||
|
|
||||||
struct ResultRec {
|
|
||||||
Word recvCount;
|
|
||||||
Word result;
|
|
||||||
} resultRec;
|
|
||||||
|
|
||||||
char afpOverTCPZone[] = "AFP over TCP";
|
char afpOverTCPZone[] = "AFP over TCP";
|
||||||
|
|
||||||
|
typedef struct GSString1024 {
|
||||||
|
Word length;
|
||||||
|
char text[1024];
|
||||||
|
} GSString1024;
|
||||||
|
|
||||||
|
typedef struct ResultBuf1024 {
|
||||||
|
Word bufSize;
|
||||||
|
GSString1024 bufString;
|
||||||
|
} ResultBuf1024;
|
||||||
|
|
||||||
|
CreateRecGS createRec;
|
||||||
|
OpenRecGS openRec;
|
||||||
|
IORecGS writeRec;
|
||||||
|
RefNumRecGS closeRec;
|
||||||
|
NameRecGS destroyRec;
|
||||||
|
RefInfoRecGS getRefInfoRec;
|
||||||
|
|
||||||
|
ResultBuf1024 filename = { sizeof(ResultBuf1024) };
|
||||||
|
|
||||||
|
char tempFileName[] = "AFPMounter.Temp";
|
||||||
|
|
||||||
|
finderSaysBeforeOpenIn fsboRec;
|
||||||
|
|
||||||
|
GSString32 origNameString;
|
||||||
|
SFReplyRec2 sfReplyRec;
|
||||||
|
|
||||||
|
Word modifiers = 0;
|
||||||
|
|
||||||
void fillEasyMountRec(char *server, char *zone, char *volume, char *user,
|
void fillEasyMountRec(char *server, char *zone, char *volume, char *user,
|
||||||
char *password, char *volpass)
|
char *password, char *volpass)
|
||||||
{
|
{
|
||||||
|
@ -68,8 +102,6 @@ void fillEasyMountRec(char *server, char *zone, char *volume, char *user,
|
||||||
char *next;
|
char *next;
|
||||||
|
|
||||||
memset(&easyMountRec, 0, sizeof(easyMountRec));
|
memset(&easyMountRec, 0, sizeof(easyMountRec));
|
||||||
easyMountRec.size = offsetof(EasyMountRec, volume2) + 2 + strlen(volume);
|
|
||||||
easyMountRec.version = 2;
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
next = server;
|
next = server;
|
||||||
|
@ -97,67 +129,91 @@ void fillEasyMountRec(char *server, char *zone, char *volume, char *user,
|
||||||
strncpy(&easyMountRec.password[0], password, sizeof(easyMountRec.password));
|
strncpy(&easyMountRec.password[0], password, sizeof(easyMountRec.password));
|
||||||
|
|
||||||
strncpy(&easyMountRec.volpass[0], volpass, sizeof(easyMountRec.volpass));
|
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)
|
int deleteAlias(GSString255Ptr file, Boolean overwrite)
|
||||||
{
|
{
|
||||||
resultRec.recvCount = 0;
|
if (overwrite) {
|
||||||
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
|
* Zero out the data before deleting, so password isn't left
|
||||||
* domain name, so try TCP first. Otherwise try AppleTalk first.
|
* in the unallocated disk block.
|
||||||
* In either case, we proceed to try the other if we get an NBP error.
|
|
||||||
*/
|
*/
|
||||||
if (strchr(urlParts->server, '.') != NULL) {
|
memset(&easyMountRec, 0, sizeof(easyMountRec));
|
||||||
if (((result = tryConnect(proto_TCP, urlParts)) & 0xFF00) == 0x0400)
|
|
||||||
result = tryConnect(proto_AT, urlParts);
|
openRec.pCount = 3;
|
||||||
} else {
|
openRec.pathname = file;
|
||||||
if (((result = tryConnect(proto_AT, urlParts)) & 0xFF00) == 0x0400)
|
openRec.requestAccess = writeEnable;
|
||||||
result = tryConnect(proto_TCP, urlParts);
|
OpenGS(&openRec);
|
||||||
}
|
if (toolerror())
|
||||||
} else {
|
goto destroy;
|
||||||
AlertWindow(awResource, NULL, protoInvalidError);
|
|
||||||
return;
|
writeRec.pCount = 5;
|
||||||
|
writeRec.refNum = openRec.refNum;
|
||||||
|
writeRec.dataBuffer = (Pointer)&easyMountRec;
|
||||||
|
writeRec.requestCount = sizeof(EasyMountRec);
|
||||||
|
writeRec.cachePriority = cacheOff;
|
||||||
|
WriteGS(&writeRec);
|
||||||
|
if (toolerror())
|
||||||
|
goto destroy;
|
||||||
|
|
||||||
|
closeRec.pCount = 1;
|
||||||
|
closeRec.refNum = openRec.refNum;
|
||||||
|
CloseGS(&closeRec);
|
||||||
|
if (toolerror())
|
||||||
|
goto destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resultRec.recvCount == 0) {
|
destroy:
|
||||||
AlertWindow(awResource, NULL, noEasyMountError);
|
destroyRec.pCount = 1;
|
||||||
return;
|
destroyRec.pathname = file;
|
||||||
|
DestroyGS(&destroyRec);
|
||||||
|
return toolerror();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int writeAlias(GSString255Ptr file)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
createRec.pCount = 6;
|
||||||
|
createRec.pathname = file;
|
||||||
|
createRec.access = readEnable|writeEnable|renameEnable|destroyEnable;
|
||||||
|
createRec.fileType = EM_filetype;
|
||||||
|
createRec.auxType = EM_auxtype;
|
||||||
|
createRec.storageType = standardFile;
|
||||||
|
createRec.eof = sizeof(EasyMountRec);
|
||||||
|
CreateGS(&createRec);
|
||||||
|
if ((err = toolerror()))
|
||||||
|
return err;
|
||||||
|
|
||||||
|
openRec.pCount = 3;
|
||||||
|
openRec.pathname = file;
|
||||||
|
openRec.requestAccess = writeEnable;
|
||||||
|
OpenGS(&openRec);
|
||||||
|
if ((err = toolerror())) {
|
||||||
|
deleteAlias(file, FALSE);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeRec.pCount = 5;
|
||||||
|
writeRec.refNum = openRec.refNum;
|
||||||
|
writeRec.dataBuffer = (Pointer)&easyMountRec;
|
||||||
|
writeRec.requestCount = sizeof(EasyMountRec);
|
||||||
|
writeRec.cachePriority = cacheOn;
|
||||||
|
WriteGS(&writeRec);
|
||||||
|
if ((err = toolerror())) {
|
||||||
|
deleteAlias(file, TRUE);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
closeRec.pCount = 1;
|
||||||
|
closeRec.refNum = openRec.refNum;
|
||||||
|
CloseGS(&closeRec);
|
||||||
|
if ((err = toolerror())) {
|
||||||
|
deleteAlias(file, TRUE);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void finalizeURLParts(AFPURLParts *urlParts)
|
void finalizeURLParts(AFPURLParts *urlParts)
|
||||||
|
@ -176,32 +232,191 @@ void finalizeURLParts(AFPURLParts *urlParts)
|
||||||
urlParts->volpass = "";
|
urlParts->volpass = "";
|
||||||
if (urlParts->volume == NULL)
|
if (urlParts->volume == NULL)
|
||||||
urlParts->volume = "";
|
urlParts->volume = "";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Guess the protocol if it's not explicitly specified:
|
||||||
|
* If server name contains a dot it's probably an IP address
|
||||||
|
* or domain name, so use TCP. Otherwise use AppleTalk.
|
||||||
|
*/
|
||||||
|
if (urlParts->protocol == proto_unknown) {
|
||||||
|
if (strchr(urlParts->server, '.') != NULL) {
|
||||||
|
urlParts->protocol = proto_TCP;
|
||||||
|
} else {
|
||||||
|
urlParts->protocol = proto_AT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoConnect(char *url)
|
if (urlParts->protocol == proto_TCP) {
|
||||||
{
|
urlParts->zone = afpOverTCPZone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AFPURLParts prepareURL(char *url) {
|
||||||
|
int result;
|
||||||
AFPURLParts urlParts;
|
AFPURLParts urlParts;
|
||||||
int validationError;
|
|
||||||
|
|
||||||
urlParts = parseAFPURL(url);
|
urlParts = parseAFPURL(url);
|
||||||
|
result = validateAFPURL(&urlParts);
|
||||||
|
if (result != 0) {
|
||||||
|
AlertWindow(awResource+awButtonLayout, NULL, result);
|
||||||
|
urlParts.protocol = proto_invalid;
|
||||||
|
return urlParts;
|
||||||
|
}
|
||||||
|
finalizeURLParts(&urlParts);
|
||||||
|
return urlParts;
|
||||||
|
}
|
||||||
|
|
||||||
if (validationError = validateAFPURL(&urlParts)) {
|
void ConnectOrSave(AFPURLParts* urlParts, GSString255Ptr file, Boolean connect)
|
||||||
AlertWindow(awResource, NULL, validationError);
|
{
|
||||||
|
Word recvCount;
|
||||||
|
|
||||||
|
fillEasyMountRec(urlParts->server, urlParts->zone, urlParts->volume,
|
||||||
|
urlParts->username, urlParts->password, urlParts->volpass);
|
||||||
|
|
||||||
|
if (writeAlias(file) != 0) {
|
||||||
|
AlertWindow(awResource+awButtonLayout, NULL,
|
||||||
|
connect ? tempFileError : aliasFileError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
finalizeURLParts(&urlParts);
|
if (connect) {
|
||||||
connect(&urlParts);
|
recvCount = 0;
|
||||||
|
fsboRec.pCount = 7;
|
||||||
|
fsboRec.pathname = (pointer)file;
|
||||||
|
fsboRec.zoomRect = 0;
|
||||||
|
fsboRec.filetype = EM_filetype;
|
||||||
|
fsboRec.auxtype = EM_auxtype;
|
||||||
|
fsboRec.modifiers = modifiers;
|
||||||
|
fsboRec.theIconObj = 0;
|
||||||
|
fsboRec.printFlag = 0;
|
||||||
|
SendRequest(finderSaysBeforeOpen, sendToAll+stopAfterOne, 0,
|
||||||
|
(Long)&fsboRec, (Ptr)&recvCount);
|
||||||
|
|
||||||
|
deleteAlias(file, TRUE);
|
||||||
|
|
||||||
|
if (recvCount == 0) {
|
||||||
|
AlertWindow(awResource+awButtonLayout, NULL, noEasyMountError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoConnect(void)
|
||||||
|
{
|
||||||
|
Word i;
|
||||||
|
char *lastColon;
|
||||||
|
AFPURLParts urlParts;
|
||||||
|
|
||||||
|
GetLETextByID(wPtr, urlLine, (StringPtr)&urlBuf);
|
||||||
|
urlParts = prepareURL(urlBuf+1);
|
||||||
|
if (urlParts.protocol == proto_invalid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Generate the path name for the temp file in same dir as the CDev */
|
||||||
|
getRefInfoRec.pCount = 3;
|
||||||
|
getRefInfoRec.refNum = GetOpenFileRefNum(0); /* current resource file */
|
||||||
|
getRefInfoRec.pathname = (ResultBuf255Ptr)&filename;
|
||||||
|
GetRefInfoGS(&getRefInfoRec);
|
||||||
|
if (toolerror())
|
||||||
|
goto err;
|
||||||
|
if (filename.bufString.length > filename.bufSize - 5 - strlen(tempFileName))
|
||||||
|
goto err;
|
||||||
|
filename.bufString.text[filename.bufString.length] = 0;
|
||||||
|
lastColon = strrchr(filename.bufString.text, ':');
|
||||||
|
if (lastColon == NULL)
|
||||||
|
goto err;
|
||||||
|
strcpy(lastColon + 1, tempFileName);
|
||||||
|
filename.bufString.length = strlen(filename.bufString.text);
|
||||||
|
|
||||||
|
ConnectOrSave(&urlParts, (GSString255Ptr)&filename.bufString, TRUE);
|
||||||
|
return;
|
||||||
|
|
||||||
|
err:
|
||||||
|
/* Most error cases here should be impossible or very unlikely. */
|
||||||
|
AlertWindow(awResource+awButtonLayout, NULL, tempFileNameError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoSave(void)
|
||||||
|
{
|
||||||
|
Boolean sfStatus, loadedSF = FALSE, allocatedDP = FALSE, startedSF = FALSE;
|
||||||
|
Boolean completedOK = FALSE;
|
||||||
|
Handle dpSpace;
|
||||||
|
AFPURLParts urlParts;
|
||||||
|
|
||||||
|
GetLETextByID(wPtr, urlLine, (StringPtr)&urlBuf);
|
||||||
|
urlParts = prepareURL(urlBuf+1);
|
||||||
|
if (urlParts.protocol == proto_invalid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Load Standard File toolset if necessary */
|
||||||
|
if (!SFStatus() || toolerror()) {
|
||||||
|
if (toolerror())
|
||||||
|
loadedSF = TRUE;
|
||||||
|
LoadOneTool(0x17, 0x0303); /* Standard File */
|
||||||
|
if (toolerror())
|
||||||
|
goto err;
|
||||||
|
dpSpace = NewHandle(0x0100, GetCurResourceApp(),
|
||||||
|
attrLocked|attrFixed|attrNoCross|attrBank|attrPage, 0x000000);
|
||||||
|
if (toolerror())
|
||||||
|
goto err;
|
||||||
|
allocatedDP = TRUE;
|
||||||
|
SFStartUp(GetCurResourceApp(), (Word) *dpSpace);
|
||||||
|
if (toolerror())
|
||||||
|
goto err;
|
||||||
|
startedSF = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initially proposed file name = volume name */
|
||||||
|
origNameString.length = strlen(urlParts.volume);
|
||||||
|
if (origNameString.length > sizeof(origNameString.text))
|
||||||
|
origNameString.length = sizeof(origNameString.text);
|
||||||
|
strncpy(origNameString.text, urlParts.volume, sizeof(origNameString.text));
|
||||||
|
|
||||||
|
/* Get the file name */
|
||||||
|
memset(&sfReplyRec, 0, sizeof(sfReplyRec));
|
||||||
|
sfReplyRec.nameRefDesc = refIsNewHandle;
|
||||||
|
sfReplyRec.pathRefDesc = refIsPointer;
|
||||||
|
sfReplyRec.pathRef = (Ref) &filename;
|
||||||
|
SFPutFile2(GetMasterSCB() & scbColorMode ? 160 : 25, 40,
|
||||||
|
refIsResource, saveFilePrompt,
|
||||||
|
refIsPointer, (Ref)&origNameString, &sfReplyRec);
|
||||||
|
if (toolerror()) {
|
||||||
|
if (sfReplyRec.good)
|
||||||
|
DisposeHandle((Handle)sfReplyRec.nameRef);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the file, unless user canceled */
|
||||||
|
if (sfReplyRec.good) {
|
||||||
|
DisposeHandle((Handle)sfReplyRec.nameRef);
|
||||||
|
deleteAlias((GSString255Ptr)&filename.bufString, FALSE);
|
||||||
|
ConnectOrSave(&urlParts, (GSString255Ptr)&filename.bufString, FALSE);
|
||||||
|
}
|
||||||
|
completedOK = TRUE;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (!completedOK)
|
||||||
|
AlertWindow(awResource+awButtonLayout, NULL, saveAliasError);
|
||||||
|
if (startedSF)
|
||||||
|
SFShutDown();
|
||||||
|
if (allocatedDP)
|
||||||
|
DisposeHandle(dpSpace);
|
||||||
|
if (loadedSF)
|
||||||
|
UnloadOneTool(0x17);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoHit(long ctlID)
|
void DoHit(long ctlID)
|
||||||
{
|
{
|
||||||
if (ctlID == connectBtn) {
|
if (ctlID == connectBtn) {
|
||||||
GetLETextByID(wPtr, urlLine, (StringPtr)&urlBuf);
|
DoConnect();
|
||||||
DoConnect(urlBuf+1);
|
|
||||||
} else if (ctlID == saveAliasBtn) {
|
} else if (ctlID == saveAliasBtn) {
|
||||||
|
DoSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long DoMachine(void)
|
long DoMachine(void)
|
||||||
|
@ -216,7 +431,7 @@ long DoMachine(void)
|
||||||
GetFSTInfoGS(&fstInfoRec);
|
GetFSTInfoGS(&fstInfoRec);
|
||||||
if (toolerror() == paramRangeErr) {
|
if (toolerror() == paramRangeErr) {
|
||||||
InitCursor();
|
InitCursor();
|
||||||
AlertWindow(awResource, NULL, fstMissingError);
|
AlertWindow(awResource+awButtonLayout, NULL, fstMissingError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,6 +448,8 @@ LongWord cdevMain (LongWord data2, LongWord data1, Word message)
|
||||||
case HitCDEV: DoHit(data2); break;
|
case HitCDEV: DoHit(data2); break;
|
||||||
case InitCDEV: wPtr = (WindowPtr)data1; break;
|
case InitCDEV: wPtr = (WindowPtr)data1; break;
|
||||||
case CloseCDEV: wPtr = NULL; break;
|
case CloseCDEV: wPtr = NULL; break;
|
||||||
|
case EventsCDEV: modifiers = ((EventRecordPtr)data1)->modifiers;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret:
|
ret:
|
||||||
|
|
42
afpcdev.rez
42
afpcdev.rez
|
@ -1,7 +1,7 @@
|
||||||
#include "types.rez"
|
#include "types.rez"
|
||||||
|
|
||||||
resource rCDEVFlags (1) {
|
resource rCDEVFlags (1) {
|
||||||
wantMachine+wantHit+wantInit+wantClose,
|
wantMachine+wantHit+wantInit+wantClose+wantEvents,
|
||||||
1, /* enabled */
|
1, /* enabled */
|
||||||
1, /* version */
|
1, /* version */
|
||||||
1, /* min ROM version */
|
1, /* min ROM version */
|
||||||
|
@ -71,6 +71,8 @@ resource rIcon (1) {
|
||||||
|
|
||||||
#define helpTxt 5
|
#define helpTxt 5
|
||||||
|
|
||||||
|
#define saveFilePrompt 100
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Controls in the control panel window
|
* Controls in the control panel window
|
||||||
*/
|
*/
|
||||||
|
@ -173,6 +175,7 @@ resource rTextForLETextBox2 (helpWindow+helpTxt) {
|
||||||
"volume (to connect using AppleTalk)\n"
|
"volume (to connect using AppleTalk)\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
resource rPString(saveFilePrompt) { "Save server alias as:" };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Error messages
|
* Error messages
|
||||||
|
@ -180,6 +183,10 @@ resource rTextForLETextBox2 (helpWindow+helpTxt) {
|
||||||
|
|
||||||
#define fstMissingError 3000
|
#define fstMissingError 3000
|
||||||
#define noEasyMountError 3001
|
#define noEasyMountError 3001
|
||||||
|
#define tempFileError 3002
|
||||||
|
#define aliasFileError 3003
|
||||||
|
#define tempFileNameError 3004
|
||||||
|
#define saveAliasError 3005
|
||||||
|
|
||||||
#define protoInvalidError 4000
|
#define protoInvalidError 4000
|
||||||
#define noServerOrVolumeNameError 4001
|
#define noServerOrVolumeNameError 4001
|
||||||
|
@ -189,7 +196,7 @@ resource rTextForLETextBox2 (helpWindow+helpTxt) {
|
||||||
#define usernameTooLongError 4005
|
#define usernameTooLongError 4005
|
||||||
#define passwordTooLongError 4006
|
#define passwordTooLongError 4006
|
||||||
#define volpassTooLongError 4007
|
#define volpassTooLongError 4007
|
||||||
#define userXorPasswordError 4008
|
#define passwordWithoutUserError 4008
|
||||||
#define badUAMError 4009
|
#define badUAMError 4009
|
||||||
|
|
||||||
resource rAlertString (fstMissingError) {
|
resource rAlertString (fstMissingError) {
|
||||||
|
@ -257,9 +264,9 @@ resource rAlertString (volpassTooLongError) {
|
||||||
":^#0\$00"
|
":^#0\$00"
|
||||||
};
|
};
|
||||||
|
|
||||||
resource rAlertString (userXorPasswordError) {
|
resource rAlertString (passwordWithoutUserError) {
|
||||||
"42:"
|
"42:"
|
||||||
"Please specify both a username and a password, or neither."
|
"When a password is specified, a user name must also be given."
|
||||||
":^#0\$00"
|
":^#0\$00"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -270,3 +277,30 @@ resource rAlertString (badUAMError) {
|
||||||
":^#0\$00"
|
":^#0\$00"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
resource rAlertString (tempFileError) {
|
||||||
|
"82:"
|
||||||
|
"There was an error writing the temporary file used by the "
|
||||||
|
"AFPMounter control panel. Please make sure the directory "
|
||||||
|
"containing the AFPMounter control panel is writable and "
|
||||||
|
"remove the AFPMounter.Temp file if it is present."
|
||||||
|
":^#0\$00"
|
||||||
|
};
|
||||||
|
|
||||||
|
resource rAlertString (aliasFileError) {
|
||||||
|
"32:"
|
||||||
|
"There was an error writing the alias file."
|
||||||
|
":^#0\$00"
|
||||||
|
};
|
||||||
|
|
||||||
|
resource rAlertString (tempFileNameError) {
|
||||||
|
"72:"
|
||||||
|
"There was an error while constructing the name for the "
|
||||||
|
"temporary file used by the AFPMounter control panel."
|
||||||
|
":^#0\$00"
|
||||||
|
};
|
||||||
|
|
||||||
|
resource rAlertString (saveAliasError) {
|
||||||
|
"42:"
|
||||||
|
"There was an error while attempting to save the alias file."
|
||||||
|
":^#0\$00"
|
||||||
|
};
|
||||||
|
|
|
@ -119,7 +119,7 @@ AFPURLParts parseAFPURL(char *url)
|
||||||
|
|
||||||
sep = strchr(urlParts.server, ':');
|
sep = strchr(urlParts.server, ':');
|
||||||
if (sep && (urlParts.protocol == proto_AT ||
|
if (sep && (urlParts.protocol == proto_AT ||
|
||||||
(urlParts.protocol == proto_unknown
|
((urlParts.protocol == proto_unknown || urlParts.protocol == proto_TCP)
|
||||||
&& strspn(sep+1, "0123456789") != strlen(sep+1))))
|
&& strspn(sep+1, "0123456789") != strlen(sep+1))))
|
||||||
{
|
{
|
||||||
*sep = 0;
|
*sep = 0;
|
||||||
|
@ -136,7 +136,8 @@ AFPURLParts parseAFPURL(char *url)
|
||||||
/* Check if an AFP URL is suitable for our AFP mounter */
|
/* Check if an AFP URL is suitable for our AFP mounter */
|
||||||
int validateAFPURL(AFPURLParts *urlParts)
|
int validateAFPURL(AFPURLParts *urlParts)
|
||||||
{
|
{
|
||||||
if (urlParts->server == NULL || urlParts->volume == NULL)
|
if (urlParts->server == NULL || urlParts->volume == NULL
|
||||||
|
|| *urlParts->server == 0 || *urlParts->volume == 0)
|
||||||
return noServerOrVolumeNameError;
|
return noServerOrVolumeNameError;
|
||||||
if (urlParts->protocol == proto_invalid)
|
if (urlParts->protocol == proto_invalid)
|
||||||
return protoInvalidError;
|
return protoInvalidError;
|
||||||
|
@ -153,13 +154,9 @@ int validateAFPURL(AFPURLParts *urlParts)
|
||||||
if (urlParts->volpass != NULL && strlen(urlParts->volpass) > VOLPASS_MAX)
|
if (urlParts->volpass != NULL && strlen(urlParts->volpass) > VOLPASS_MAX)
|
||||||
return volpassTooLongError;
|
return volpassTooLongError;
|
||||||
|
|
||||||
/* Must have username & password, or neither */
|
if (urlParts->password != NULL && *urlParts->password != 0
|
||||||
if (urlParts->username == NULL)
|
&& (urlParts->username == NULL || *urlParts->username == 0))
|
||||||
if (urlParts->password != NULL && *urlParts->password != 0)
|
return passwordWithoutUserError;
|
||||||
return userXorPasswordError;
|
|
||||||
if (urlParts->password == NULL)
|
|
||||||
if (urlParts->username != NULL && *urlParts->username != 0)
|
|
||||||
return userXorPasswordError;
|
|
||||||
|
|
||||||
if (urlParts->auth != NULL) {
|
if (urlParts->auth != NULL) {
|
||||||
if (strncasecmp(urlParts->auth, "No User Authent", 16) == 0) {
|
if (strncasecmp(urlParts->auth, "No User Authent", 16) == 0) {
|
||||||
|
@ -167,8 +164,7 @@ int validateAFPURL(AFPURLParts *urlParts)
|
||||||
|| (urlParts->password != NULL && *urlParts->password != 0))
|
|| (urlParts->password != NULL && *urlParts->password != 0))
|
||||||
return badUAMError;
|
return badUAMError;
|
||||||
} else if (strncasecmp(urlParts->auth, "Randnum Exchange", 17) == 0) {
|
} else if (strncasecmp(urlParts->auth, "Randnum Exchange", 17) == 0) {
|
||||||
if (urlParts->username == NULL || *urlParts->username == 0
|
if (urlParts->username == NULL || *urlParts->username == 0)
|
||||||
|| urlParts->password == NULL)
|
|
||||||
return badUAMError;
|
return badUAMError;
|
||||||
} else {
|
} else {
|
||||||
/* unknown/unsupported UAM */
|
/* unknown/unsupported UAM */
|
||||||
|
|
|
@ -30,7 +30,7 @@ typedef struct AFPURLParts {
|
||||||
#define usernameTooLongError 4005
|
#define usernameTooLongError 4005
|
||||||
#define passwordTooLongError 4006
|
#define passwordTooLongError 4006
|
||||||
#define volpassTooLongError 4007
|
#define volpassTooLongError 4007
|
||||||
#define userXorPasswordError 4008
|
#define passwordWithoutUserError 4008
|
||||||
#define badUAMError 4009
|
#define badUAMError 4009
|
||||||
|
|
||||||
AFPURLParts parseAFPURL(char *url);
|
AFPURLParts parseAFPURL(char *url);
|
||||||
|
|
Loading…
Reference in New Issue