DIRECTORY IO USING [Close, PutFR, STREAM], Rope USING [Length, ROPE], STP USING [ErrorCode, FileInfoObject], STPOps USING [ CollectCode, CollectString, ErrorIfNextNotEOC, GetCommand, GetServerType, Handle, markComment, markIAmVersion, markNo, Object, PList, PListArray, ProtocolError, PutCommand, UserProperties], STPReplyCode USING [ReplyCode], PupStream USING [ CloseReason, GetPupAddress, PupAddress, PupByteStreamCreate, PupNameTrouble, PupPackageDestroy, PupPackageMake, StreamClosing, veryLongWait], PupTypes USING [ftpSoc]; STPsA: CEDAR PROGRAM IMPORTS IO, PupStream, Rope, STPOps EXPORTS STP, STPOps = BEGIN OPEN PupStream, STPOps; Error: PUBLIC SIGNAL [ stp: STPOps.Handle, code: STP.ErrorCode, error: Rope.ROPE, reply: CHARACTER _ 0C] = CODE; Object: PUBLIC TYPE = STPOps.Object; Close: PUBLIC PROCEDURE [stp: STPOps.Handle] = BEGIN nilByteStream: BOOLEAN; IF stp = NIL THEN RETURN; nilByteStream _ stp.byteStream = NIL; CloseInternal[stp]; IF nilByteStream THEN ERROR Error[stp: stp, code: noConnection, error: "Attempt to Close a NIL connection"]; END; CloseInternal: PUBLIC PROCEDURE [stp: STPOps.Handle] = BEGIN IF stp = NIL THEN RETURN; stp.plist _ DestroyPList[stp.plist]; IF stp.byteStream # NIL THEN BEGIN stp.byteStream.Close[ ! PupStream.StreamClosing => CONTINUE]; stp.byteStream _ NIL; END; END; Create: PUBLIC PROCEDURE RETURNS [stp: STPOps.Handle] = BEGIN OPEN PupTypes; PupStream.PupPackageMake[]; stp _ NEW[STPOps.Object _ []]; RETURN[stp]; END; Destroy: PUBLIC PROCEDURE [stp: STPOps.Handle] RETURNS [Handle] = BEGIN IF stp = NIL THEN RETURN[NIL]; IF stp.byteStream # NIL THEN Close[stp]; PupStream.PupPackageDestroy[]; RETURN[NIL]; END; Open: PUBLIC PROCEDURE [stp: STPOps.Handle, host: Rope.ROPE] RETURNS [herald: Rope.ROPE] = BEGIN reason: PupStream.CloseReason; IF stp = NIL THEN RETURN["\"NIL\" STP handle"]; IF stp.byteStream # NIL THEN ERROR Error[stp, alreadyAConnection, "You already have a connection?"]; BEGIN server: PupStream.PupAddress = PupStream.GetPupAddress[PupTypes.ftpSoc, host ! PupStream.PupNameTrouble => GenerateErrorString[stp, noSuchHost, e]]; stp.byteStream _ PupStream.PupByteStreamCreate[ server, PupStream.veryLongWait ! PupStream.StreamClosing => {reason _ why; GOTO streamClosing}]; stp.plist _ MakePList[]; stp.info _ NEW[STP.FileInfoObject _ []]; stp.gotMark _ FALSE; stp.serverType _ GetServerType[host]; PutCommand[stp, markIAmVersion, 1C, "STP calling" ! PupStream.StreamClosing => {reason _ why; GOTO streamClosing}]; BEGIN code: CHARACTER; mark: [0..256); [mark, code, herald] _ GetCommand[stp]; IF mark # markIAmVersion THEN GenerateProtocolError[stp, badVersion, mark, code]; ErrorIfNextNotEOC[stp]; END; EXITS streamClosing => {CloseInternal[stp]; GenerateStreamClosingError[stp, reason]}; END; END; DestroyPList: PUBLIC PROCEDURE [plist: PList] RETURNS [PList] = BEGIN RETURN[NIL] END; MakePList: PUBLIC PROCEDURE RETURNS [plist: PList] = BEGIN RETURN[ NEW[PListArray _ ALL[NIL]] ]; END; ErrorCodeToSTPErrorCode: PUBLIC PROCEDURE [ errorCode: STP.ErrorCode, code: CHARACTER] RETURNS [STP.ErrorCode] = { replyCode: STPReplyCode.ReplyCode = LOOPHOLE[code]; RETURN[SELECT replyCode FROM null => errorCode, badCommand => protocolError, noUserName => illegalUserName, illegalCommand => protocolError, badPList => protocolError, illegalServerFilename => illegalFileName, illegalDirectory => illegalFileName, illegalNameBody => illegalFileName, illegalVersion => illegalFileName, illegalType => accessError, illegalCharacterSize => accessError, illegalEOLConversion => accessError, illegalUserName => illegalUserName, illegalUserPassword => illegalUserPassword, illegalUserAccount => illegalUserAccount, illegalConnectName => illegalConnectName, illegalConnectPassword => illegalConnectPassword, illegalCreationDate => illegalFileName, illegalWriteDate => illegalFileName, illegalReadDate => illegalFileName, illegalAuthor => illegalFileName, illegalDevice => illegalFileName, fileNotFound => noSuchFile, accessDenied => accessDenied, inconsistent => protocolError, fileDataError => errorCode, tooLong => requestRefused, dontSend => errorCode, notCompleted => errorCode, transientError => errorCode, permanentError => errorCode, fileBusy => accessError, ENDCASE => errorCode] -- can't do any better--}; GenerateErrorString: PUBLIC PROCEDURE [ stp: STPOps.Handle, errorCode: STP.ErrorCode, string: Rope.ROPE, code: CHARACTER _ 0C] = BEGIN ERROR Error[stp, ErrorCodeToSTPErrorCode[errorCode, code], IF string.Length[] # 0 THEN string ELSE SELECT errorCode FROM noSuchHost => "No such host!", noRouteToNetwork => "No route to network!", noNameLookupResponse => "Name lookup server is not responding", alreadyAConnection => "You already have a connection!", noConnection => "Please open a connection!", connectionClosed => "Connection closed (local or remote)!", connectionRejected => "Connection rejected by remote host!", connectionTimedOut => "Connection timed out!", accessDenied => "Access denied by remote server!", illegalUserName => "Invalid or illegal UserName!", illegalUserPassword => "Invalid or illegal UserPassword!", illegalUserAccount => "Invalid or illegal UserAccount!", illegalConnectName => "Invalid or illegal ConnectName!", illegalConnectPassword => "Invalid or illegal ConnectPassword!", credentailsMissing => "Name and/or Password not supplied!", protocolError => "Internal FTP protocol error!", illegalFileName => "Illegal filename!", noSuchFile => "File not found!", requestRefused => "Request refused by remote host!", accessError => "Illegal access attempt on remote stream!", undefinedError => "Undefined error!", ENDCASE => ERROR, code]; END; GenerateStreamClosingError: PUBLIC PROCEDURE [stp: STPOps.Handle, why: PupStream.CloseReason] = BEGIN GenerateErrorString[stp, SELECT why FROM localClose, remoteClose => connectionClosed, noRouteToNetwork => noRouteToNetwork, transmissionTimeout => connectionTimedOut, remoteReject => connectionRejected, ENDCASE => ERROR, NIL]; END; GenerateProtocolError: PUBLIC PROCEDURE [ stp: STPOps.Handle, type: ProtocolError, mark: [0..256), code: CHARACTER _ 0C] = BEGIN text: Rope.ROPE = IO.PutFR["%g, mark = %b, code = %b", [rope[SELECT type FROM badVersion => "Incompatable protocol version", badMark => "Invalid or undefined mark byte", badPList => "Invalid or malformed property list", eocExpected => "End-Of-Command mark byte expected", noCode => "error code is required after error mark byte", ENDCASE => ERROR]], [integer[mark]], [integer[code-0C]] ]; ERROR Error[stp, protocolError, text, code]; END; SelectError: PUBLIC PROCEDURE [ stp: STPOps.Handle, s: Rope.ROPE , mark: [0..256)] = BEGIN code: CHARACTER _ 0C; IF mark = markNo OR mark = markComment THEN BEGIN IF mark # markComment THEN code _ CollectCode[stp]; stp.remoteString _ CollectString[stp]; GenerateErrorString[ stp, requestRefused, IF stp.remoteString.Length[] = 0 THEN s ELSE stp.remoteString, code]; END ELSE GenerateProtocolError[stp, badMark, mark, code]; END; END. -- of STPsA pfile: STPsA.mesa - Simple/Stream Transfer Protocol Initialization and Error stuff in here Edited by: Smokey, 16-Jul-81 14:54:32 Karlton, 9-Dec-81 18:23:36 Evans, Nov 14, 1980 9:35 AM Davirro, 24-Sep-82 9:03:45 Schmidt January 20, 1983 6:05 pm Andrew Birrell June 1, 1983 3:03 pm Global Data Public Interface Routines PList Utilities Error generation routines ÊD˜Jšœ2™2Jšœ&™&Jšœ ™ Jšœ™Jšœ™Jšœ™Jšœ™Jšœ ™ Jšœ#™#J˜šÏk ˜ Jšœœœ˜ Jšœœ œ˜Jšœœ˜&šœœ˜J˜IJ˜4J˜>—Jšœ œ ˜šœ œ˜J˜LJ˜@—Jšœ œ ˜J˜—šœœ˜Jšœœ˜#Jšœœ ˜J˜Jšœœ˜J˜Jšœ ™ J˜šœœœ˜Jš œœœ œ œ˜Y—J˜Jšœœœ˜$J˜Jšœ™J˜šÏnœœ œ˜.Jš˜Jšœœ˜Jšœœœœ˜Jšœ!œ˜%J˜šœ˜JšœQ˜V—Jšœ˜J˜—šž œœ œ˜6Jš˜Jšœœœœ˜J˜$šœœ˜Jš˜Jšœ3œ˜=Jšœœ˜Jšœ˜—Jšœ˜J˜—šžœœ œœ˜7Jšœœ ˜J˜Jšœœ˜Jšœ˜ Jšœ˜J˜—šžœœ œœ ˜AJš˜Jš œœœœœ˜Jšœœœ ˜(J˜Jšœœ˜ Jšœ˜J˜—šžœœ œ!œ˜J˜—Jš˜—Jšœ1˜5Jšœ˜J˜—JšœŸ ˜J˜J˜——…—b$