DIRECTORY AlpineEnvironment USING[ NeededAccess, OperationFailure, Principal, UnknownType], AlpDirectory USING[ Error ], AlpineDirectory USING[ ErrorType ], AlpInstance USING[ AccessFailed, Create, Handle, LockFailed, Failed, OperationFailed, PossiblyDamaged, StaticallyInvalid, Unknown], AlpTransaction USING[ Create, Finish, Handle, OperationFailed, Outcome], AMTypes USING[ IndexToName, Type], FS USING[ Error], IO, PrincOpsUtils USING[ IsBound ], Rope, RPC USING[ CallFailed, CallFailure, EncryptionKey, MakeKey], UserCredentials USING[ Get ], YodelData; YodelSignalsImpl: CEDAR PROGRAM IMPORTS AlpDirectory, AlpInstance, AlpTransaction, AMTypes, FS, IO, PrincOpsUtils, Rope, RPC, UserCredentials EXPORTS YodelData = BEGIN OPEN YodelData; ROPE: TYPE = Rope.ROPE; PerformOp: PUBLIC PROC[ performProc: PerformProc, server: ROPE, user: ROPE _ NIL, password: ROPE _ NIL] RETURNS [LIST OF REF ANY] = { failureName: ROPE _ "" ; userName, userPassword, keyRope: ROPE; caller: AlpineEnvironment.Principal ; key: RPC.EncryptionKey; inst: AlpInstance.Handle _ NIL; trans: AlpTransaction.Handle _ NIL ; outcome: AlpTransaction.Outcome _ unknown; result: LIST OF REF ANY _ NIL ; { ENABLE BEGIN RPC.CallFailed => { type: AMTypes.Type _ CODE[RPC.CallFailure]; failure: RPC.CallFailure; count: CARDINAL _ 1 ; failureName _ "*unknown*"; FOR failure IN RPC.CallFailure DO IF why = failure THEN { failureName _ AMTypes.IndexToName[type: type, index: count]; }; count _ count + 1 ; ENDLOOP; GOTO RPCFailed; }; AlpInstance.StaticallyInvalid => GOTO statInvalid ; AlpInstance.Unknown =>{ type: AMTypes.Type _ CODE[AlpineEnvironment.UnknownType]; failure: AlpineEnvironment.UnknownType; count: CARDINAL _ 1 ; failureName _ "*unknown*"; IF what = AlpineEnvironment.UnknownType.owner THEN GOTO badOwner; IF what = AlpineEnvironment.UnknownType.transID THEN GOTO badTransID; FOR failure IN AlpineEnvironment.UnknownType DO IF what = failure THEN { failureName _ AMTypes.IndexToName[type: type, index: count]; }; count _ count + 1 ; ENDLOOP; GOTO alpUnknown; }; AlpInstance.AccessFailed =>{ type: AMTypes.Type _ CODE[AlpineEnvironment.NeededAccess]; failure: AlpineEnvironment.NeededAccess; count: CARDINAL _ 1 ; failureName _ "*unknown*"; FOR failure IN AlpineEnvironment.NeededAccess DO IF missingAccess = failure THEN { failureName _ AMTypes.IndexToName[type: type, index: count]; }; count _ count + 1 ; ENDLOOP; GOTO accFail; }; AlpInstance.OperationFailed => { type: AMTypes.Type _ CODE[AlpineEnvironment.OperationFailure]; failure: AlpineEnvironment.OperationFailure; count: CARDINAL _ 1 ; failureName _ "*unknown*"; FOR failure IN AlpineEnvironment.OperationFailure DO IF why = failure THEN { failureName _ AMTypes.IndexToName[type: type, index: count]; }; count _ count + 1 ; ENDLOOP; GOTO opFail; }; AlpDirectory.Error => { typeCode: AMTypes.Type _ CODE[AlpineDirectory.ErrorType]; failure: AlpineDirectory.ErrorType; count: CARDINAL _ 1 ; failureName _ "*unknown*"; FOR failure IN AlpineDirectory.ErrorType DO IF type = failure THEN { failureName _ AMTypes.IndexToName[type: typeCode, index: count]; }; count _ count + 1 ; ENDLOOP; GOTO dirError; }; AlpInstance.LockFailed => GOTO lockFail; AlpInstance.PossiblyDamaged => GOTO possDamaged; AlpTransaction.OperationFailed => GOTO alpineBusy; AlpInstance.Failed => { SELECT why FROM alpineDownOrCommunications => { failureName _ " alpine or communications are down"; GOTO alpineError ; }; alpineDown => { failureName _ " alpine server is down"; GOTO alpineError ; }; authenticateFailed => { failureName _ " of authentication error- suspect bad user name or password"; GOTO alpineError ; }; badCallee => { failureName _ " of bad server name"; GOTO alpineError ; }; grapevineDownOrCommunications => { failureName _ " communications or server are down"; GOTO alpineError ; }; mismatch => { failureName _ " mismatch (for example, version incompatibility)"; GOTO alpineError ; }; ENDCASE ; }; FS.Error => { failureName _ error.explanation ; GOTO FSError ; }; IO.Error => { SELECT ec FROM SyntaxError => { failureName _ "Syntax Error"; GOTO syntaxError ;} ; ENDCASE ; }; END; TRUSTED BEGIN IF NOT PrincOpsUtils.IsBound[link: LOOPHOLE[AlpInstance.Create]] THEN GOTO notBound ; END; [userName, userPassword] _ UserCredentials.Get[]; IF (Rope.Equal[user,""] OR Rope.Equal[user,NIL]) THEN caller _ userName ELSE caller _ user ; IF (Rope.Equal[password,""] OR Rope.Equal[password,NIL]) THEN keyRope _ userPassword ELSE keyRope _ password ; TRUSTED BEGIN key _ RPC.MakeKey[keyRope]; END; IF Rope.Match[pattern: "*.alpine", object: server, case: FALSE] THEN { inst _ AlpInstance.Create[fileStore: server, caller: caller, key: key]; trans _ AlpTransaction.Create[inst]; }; result _ performProc[trans: trans, serverForTrans: server, caller: caller, key: key]; IF trans # NIL THEN { outcome _ AlpTransaction.Finish[trans, commit]; }; RETURN[result]; EXITS RPCFailed => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[IO.PutFR["RPC failure: %g", IO.rope[failureName]],NIL]]; }; alpineBusy => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[NARROW["Alpine server is busy - please try again later", ROPE], NIL]]; }; dirError => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[IO.PutFR["Alpine Directory Error: %g", IO.rope[failureName]],NIL]]; }; accFail => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[IO.PutFR["Alpine denied access because client is not in the %g access control list", IO.rope[failureName]],NIL ]]; }; lockFail => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[NARROW["Alpine server has a conflict or timed out a lock - please try again later", ROPE], NIL]]; }; opFail => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[IO.PutFR["Alpine Instance Operation Failed: %g", IO.rope[failureName]],NIL]]; }; possDamaged => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[NARROW["Alpine server reports possible damage", ROPE], NIL]]; }; alpUnknown => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[IO.PutFR["Alpine Instance Unknown Type: %g", IO.rope[failureName]],NIL]]; }; badOwner => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[NARROW["Alpine Unknown Type: owner -- suspect bad directory, owner or access list name", ROPE], NIL]]; }; badTransID => { RETURN[CONS[ NARROW["Alpine Unknown Type: transID -- suspect transaction has aborted or that the server has crashed and restarted", ROPE], NIL]]; }; statInvalid => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[NARROW["Alpine Statically Invalid error - suspect unreasonable property value or Yodel bug", ROPE], NIL]]; }; notBound => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[NARROW["unbound error- suspect AlpineUserImpls has not been run", ROPE], NIL]]; }; alpineError => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[IO.PutFR["Alpine error because %g",IO.rope[failureName]],NIL]]; }; FSError => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[IO.PutFR["FS could not perform operation because %g", IO.rope[failureName]], NIL]]; }; syntaxError => { IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort ! RPC.CallFailed => CONTINUE;]; RETURN[CONS[IO.PutFR["Syntax error in input: %g", IO.rope[failureName]],NIL]]; }; }; }; END. *YodelSignalsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Yodel: Signal Handler Last Edited by: Carl Hauser, May 22, 1986 1:46:55 pm PDT Bob Hagmann June 11, 1985 9:51:23 am PDT This procedure checks to be sure Alpine is bound, and then calls the PerformProc. Most signals from Alpine are caught, and appropiate lists of ropes are returned. Bob Hagmann June 10, 1985 4:57:53 pm PDT reformatted Bob Hagmann January 9, 1986 5:17:23 pm PST Added catch phrases for RPC.CallFailed inside the EXIT clauses changes to: PerformOp Κ ±˜šœ™Icodešœ Οmœ1™<—Jšœ™šœ™K™(K™(—J˜J˜JšΟk ˜ ˜šžœ,˜1J˜ ——Jšœžœ˜)Jšœžœ˜#šœ žœ3˜EJ˜>—Jšœžœ4˜HJšœ žœ˜#Jšžœžœ ˜Jšžœ˜Jšœžœ ˜J˜Jšžœžœ3˜?Jšœžœ˜J˜ J˜Jšœžœž˜Jšžœ5žœžœžœ˜mJ˜šžœ ˜J˜J˜—J˜šžœžœ ˜J˜—˜J˜—J˜J˜Jšžœžœžœ˜˜JšœQ™QJšœP™P—šΟn œžœžœ$žœ˜?Jš œžœžœ žœžœ˜'š žœžœžœžœžœ˜Jšœ žœ˜Jšœ!žœ˜&J˜%Jšœžœ˜Jšœžœ˜Jšœžœ˜$J˜*š œžœžœžœžœžœ˜J˜———˜šžœžœ˜ šžœ˜Jšœžœžœ˜+Jšœ žœ ˜Jšœžœ˜J˜šžœ žœžœ ž˜!šžœžœ˜J˜<—J˜J˜—Jšžœ˜Jšžœ ˜—J˜Jšœ!žœ˜3˜Jšœžœ ˜9J˜'Jšœžœ˜J˜Jšžœ-žœžœ ˜BJšžœ/žœžœ ˜Fšžœ žœž˜/šžœžœ˜J˜<—J˜J˜—Jšžœ˜Jšžœ ˜J˜˜Jšœžœ!˜:J˜(Jšœžœ˜J˜šžœ žœ ž˜0šžœžœ˜!J˜<—J˜J˜—Jšžœ˜Jšžœ ˜ —J˜˜ Jšœžœ%˜>J˜,Jšœžœ˜J˜šžœ žœ$ž˜4šžœžœ˜J˜<—J˜J˜—Jšžœ˜Jšžœ˜ —J˜˜Jšœžœ˜9J˜#Jšœžœ˜J˜šžœ žœž˜+šžœžœ˜J˜@—J˜J˜—Jšžœ˜Jšžœ ˜—J˜Jšœžœ ˜(Jšœžœ ˜0Jšœ"žœ ˜2˜šžœž˜˜J˜3Jšžœ˜J˜—˜J˜'Jšžœ˜J˜—˜J˜LJšžœ˜J˜—˜J˜$Jšžœ˜J˜—˜"J˜4Jšžœ˜J˜—˜ J˜AJšžœ˜J˜——Jšžœ˜ —J˜šžœ ˜ ˜!Jšžœ ˜——J˜J˜šžœ ˜ šžœž˜˜J˜Jšžœ˜——Jšžœ˜ J˜—J˜J˜———˜Jšžœ˜J˜—J˜˜šžœž˜ Jš žœžœžœžœžœ ˜U—Jšžœ˜J˜J˜1šžœžœžœžœ˜HJšžœ˜—šžœžœžœžœ˜TJšžœ˜—šžœžœžœžœ˜.J˜—šžœ7žœžœ˜FJ˜GJ˜$J˜—J˜JšœU˜UJ˜šžœ žœžœ˜J˜/J˜—J˜Jšžœ ˜J˜šž˜˜Jš žœ žœžœ0žœžœ˜`Jš žœžœžœžœžœ˜DJ˜—˜Jš žœ žœžœ0žœžœ˜`Jš žœžœžœ3žœžœ˜RJ˜—˜ Jš žœ žœžœ0žœžœ˜`Jšžœžœžœ$˜2Jšžœžœ˜J˜—˜ Jš žœ žœžœ0žœžœ˜`Jš žœžœžœSžœžœ˜~J˜—˜ Jš žœ žœžœ0žœžœ˜`Jš žœžœžœNžœžœ˜mJ˜—˜ Jš žœ žœžœ0žœžœ˜`Jš žœžœžœ/žœžœ˜YJ˜—˜Jš žœ žœžœ0žœžœ˜`Jš žœžœžœ*žœžœ˜IJ˜—˜Jš žœ žœžœ0žœžœ˜`Jš žœžœžœ+žœžœ˜UJ˜—˜ Jš žœ žœžœ0žœžœ˜`Jš žœžœžœSžœžœ˜rJ˜—šœ˜Jšžœžœ˜ Jšžœqžœžœ˜„J˜—˜Jš žœ žœžœ0žœžœ˜`Jš žœžœžœWžœžœ˜vJ˜—˜ Jš žœ žœžœ0žœžœ˜`Jš žœžœžœ<žœžœ˜[J˜—˜Jš žœ žœžœ0žœžœ˜`Jš žœžœžœ!žœžœ˜KJ˜—˜ Jš žœ žœžœ0žœžœ˜`š žœžœžœ4žœžœ˜_J˜——˜Jš žœ žœžœ0žœžœ˜`Jš žœžœžœ$žœžœ˜NJ˜—J˜——J˜˜J˜—J˜J˜J˜Jšžœ˜J˜™(Kšœ ™ —™*Kšœ>™>Kšœ Οr ™—K™—…—X+3