<> <> <> <> <> <> <> <<>> DIRECTORY BasicTime USING [GMT, Now], Commander USING [CommandProc, Handle, Register], Convert USING [RopeFromCard], FingerOps, IO, RemoteFingerOpsRpcControl, Rope, SymTab USING [Create, Store, Ref]; FingerCmd: CEDAR MONITOR IMPORTS BasicTime, Commander, Convert, FingerOps, IO, RemoteFingerOpsRpcControl, Rope, SymTab = BEGIN fingerErrorCode: FingerOps.Reason; SetifyList: PROC [list: LIST OF Rope.ROPE] RETURNS [LIST OF Rope.ROPE] <> ~ { table: SymTab.Ref _ SymTab.Create[]; newList: LIST OF Rope.ROPE _ NIL; FOR ropeList: LIST OF Rope.ROPE _ list, ropeList.rest UNTIL ropeList = NIL DO IF SymTab.Store[table, ropeList.first, NIL] THEN newList _ CONS[ropeList.first, newList] ENDLOOP; RETURN[newList] }; -- SetifyList PerformFingerAtExec: ENTRY Commander.CommandProc = BEGIN <> nothingToDo:BOOLEAN _ TRUE; BEGIN ENABLE BEGIN IO.EndOfStream => { IF nothingToDo THEN IO.Put[cmd.out, IO.rope["Usage: Finger usernamePattern-list\n"]]; CONTINUE }; FingerOps.FingerError => { fingerErrorCode _ reason; GOTO FingerProblem }; END; Break: IO.BreakProc = BEGIN RETURN[IF char IN [IO.NUL..IO.SP] THEN sepr ELSE other] END; stream: IO.STREAM _ IO.RIS[cmd.commandLine]; WHILE TRUE DO -- stop when command line is exhausted and IO.EndOfStream is raised userNamePattern: Rope.ROPE _ IO.GetTokenRope[stream, Break].token; fingerResult: LIST OF Rope.ROPE _ FingerOps.GetMatchingPersons[pattern: userNamePattern]; matches: CARDINAL _ 0; nothingToDo _ FALSE; FOR list: LIST OF Rope.ROPE _ fingerResult, list.rest WHILE list # NIL DO matches _ matches + 1 ENDLOOP; SELECT matches FROM 0 => IO.PutRope[cmd.out, Rope.Cat["\nThere were no matches on the pattern \"", userNamePattern, "\".\n"]]; 1 => IO.PutRope[cmd.out, Rope.Cat["\nThere was 1 match on the pattern \"", userNamePattern, "\":\n"]]; ENDCASE => IO.PutRope[cmd.out, Rope.Cat["\nThere were ", Convert.RopeFromCard[matches], " matches on the pattern \"", userNamePattern, "\":\n"]]; UNTIL fingerResult = NIL DO propList: LIST OF FingerOps.PropPair = FingerOps.GetUserProps[fingerResult.first]; <> IO.PutRope[cmd.out, Rope.Cat["\n\"", fingerResult.first, "\""]]; FOR p: LIST OF FingerOps.PropPair _ propList, p.rest UNTIL p = NIL DO IO.Put[cmd.out, IO.rope["\n "], IO.atom[p.first.prop]]; IO.Put[cmd.out, IO.rope[": "], IO.rope[p.first.val]] ENDLOOP; fingerResult _ fingerResult.rest; IO.PutRope[cmd.out, "\n"] ENDLOOP; ENDLOOP; EXITS FingerProblem => { IO.PutRope[cmd.out, SELECT fingerErrorCode FROM Aborted => "\n... Transaction Aborted; Retry Finger Operation", Error => "\n... Internal Finger Error; Contact Implementor", Failure => "\n... Connection with server broken; try again later", ENDCASE => NIL ] }; END END; GetActiveUsers: ENTRY Commander.CommandProc = { ENABLE FingerOps.FingerError => { fingerErrorCode _ reason; GOTO FingerProblem }; users: LIST OF Rope.ROPE = SetifyList[FingerOps.CurrentUsers[]]; now: BasicTime.GMT = BasicTime.Now[]; IO.PutF[cmd.out, "Login TTY When\n"]; IF users = NIL THEN RETURN; FOR u: LIST OF Rope.ROPE _ users, u.rest UNTIL u = NIL DO machines: LIST OF Rope.ROPE = FingerOps.GetUserData[u.first]; FOR m: LIST OF Rope.ROPE _ machines, m.rest UNTIL m = NIL DO lastChange: FingerOps.StateChange; time: BasicTime.GMT; [lastChange ~ lastChange, time ~ time ] _ FingerOps.GetMachineData[m.first]; IO.PutF[cmd.out, "%-20g %-20g %g\n", IO.rope[u.first], IO.rope[m.first], IO.time[time]]; ENDLOOP; ENDLOOP; EXITS FingerProblem => { IO.PutRope[cmd.out, SELECT fingerErrorCode FROM Aborted => "\n... Transaction Aborted; Retry Finger Operation", Error => "\n... Internal Finger Error; Contact Implementor", Failure => "\n... Connection with server broken; try again later", ENDCASE => NIL ] }; }; FindUser: ENTRY Commander.CommandProc = { ENABLE { FingerOps.FingerError => { fingerErrorCode _ reason; GOTO FingerProblem }; IO.EndOfStream => { IO.Put[cmd.out, IO.rope["Usage: WhereIs username\n"]]; CONTINUE } }; who: Rope.ROPE = IO.GetTokenRope[IO.RIS[cmd.commandLine], IO.IDProc].token; users: LIST OF Rope.ROPE = FingerOps.CurrentUsers[]; FOR u: LIST OF Rope.ROPE _ users, u.rest UNTIL u = NIL DO IF Rope.Equal[u.first, who, FALSE] THEN { machines: LIST OF Rope.ROPE = FingerOps.GetUserData[u.first]; FOR m: LIST OF Rope.ROPE _ machines, m.rest UNTIL m = NIL DO lastChange: FingerOps.StateChange; time: BasicTime.GMT; [lastChange ~ lastChange, time ~ time ] _ FingerOps.GetMachineData[m.first]; IF lastChange = logout THEN LOOP; IO.Put[cmd.out, IO.rope[u.first]]; IO.Put[cmd.out, IO.rope[" on machine: "], IO.rope[m.first]]; IO.Put[cmd.out, IO.rope[" \n logged in at: "], IO.time[time], IO.rope["\n"]] ENDLOOP; RETURN } ENDLOOP; IO.Put[cmd.out, IO.rope["\n"], IO.rope[who], IO.rope[" is not logged in on any machine\n"]]; EXITS FingerProblem => { IO.PutRope[cmd.out, SELECT fingerErrorCode FROM Aborted => "\n... Transaction Aborted; Retry Finger Operation", Error => "\n... Internal Finger Error; Contact Implementor", Failure => "\n... Connection with server broken; try again later", ENDCASE => NIL ] }; }; FindMachine: ENTRY Commander.CommandProc = { ENABLE { FingerOps.FingerError => { fingerErrorCode _ reason; GOTO FingerProblem }; IO.EndOfStream => { IO.Put[cmd.out, IO.rope["Usage: Host machinename\n"]]; CONTINUE } }; machine: Rope.ROPE = IO.GetTokenRope[IO.RIS[cmd.commandLine], IO.IDProc].token; data: LIST OF FingerOps.PropPair _ FingerOps.GetMachineProps[machine]; IO.Put[cmd.out, IO.rope[machine]]; FOR lp: LIST OF FingerOps.PropPair _ data, lp.rest UNTIL lp = NIL DO p: FingerOps.PropPair _ lp.first; IF p.prop = $Owner THEN IO.Put[cmd.out, IO.rope[" Owner: "], IO.rope[p.val]]; IF p.prop = $Location THEN IO.Put[cmd.out, IO.rope[" Location: "], IO.rope[p.val]]; IF p.prop = $Gateway AND Rope.Equal[p.val, "TRUE"] THEN IO.PutF[cmd.out, " GATEWAY"]; IF p.prop = $Network AND Rope.Equal[p.val, "TRUE"] THEN IO.PutF[cmd.out, " NETWORK"]; ENDLOOP; IO.Put[cmd.out, IO.rope["\n"]]; EXITS FingerProblem => { IO.PutRope[cmd.out, SELECT fingerErrorCode FROM Aborted => "\n... Transaction Aborted; Retry Finger Operation\n", Error => "\n... Internal Finger Error; Contact Implementor\n", Failure => "\n... Connection with server broken; try again later\n", ENDCASE => NIL ] }; }; FreeMachines: ENTRY Commander.CommandProc = { ENABLE FingerOps.FingerError => { fingerErrorCode _ reason; GOTO FingerProblem }; machines: LIST OF Rope.ROPE = FingerOps.FreeMachines[]; FOR u: LIST OF Rope.ROPE _ machines, u.rest UNTIL u = NIL DO time: BasicTime.GMT = FingerOps.GetMachineData[u.first].time; IO.PutF[cmd.out, "%-20g last used at: %g\n", IO.rope[u.first], IO.time[time]]; ENDLOOP; IO.Put[cmd.out, IO.rope["\n"]]; EXITS FingerProblem => { IO.PutRope[cmd.out, SELECT fingerErrorCode FROM Aborted => "\n... Transaction Aborted; Retry Finger Operation\n", Error => "\n... Internal Finger Error; Contact Implementor\n", Failure => "\n... Connection with server broken; try again later\n", ENDCASE => NIL ] }; }; FingerServer: ENTRY Commander.CommandProc = { ENABLE UNWIND => NULL; action: Rope.ROPE = IO.GetTokenRope[IO.RIS[cmd.commandLine], IO.IDProc].token; SELECT TRUE FROM Rope.Equal[action, "on", FALSE] => RemoteFingerOpsRpcControl.ExportInterface[user: NIL, password: [0,0,0,0]]; Rope.Equal[action, "off", FALSE] => RemoteFingerOpsRpcControl.UnexportInterface[]; ENDCASE => IO.PutRope[cmd.out, "FingerServer on to export the RemoteFingerOps interface, FingerServer off to unexport"]; }; <> Commander.Register[key: "Finger", proc: PerformFingerAtExec, doc: "Perform a finger." ]; Commander.Register[key: "Who", proc: GetActiveUsers, doc: "lists all of the active machines and who's using each one"]; Commander.Register[key: "WhereIs", proc: FindUser, doc: "gives all of the machines currently used by the given user"]; Commander.Register[key: "Host", proc: FindMachine, doc: "provides information on a host"]; Commander.Register[key: "FreeMachines", proc: FreeMachines, doc: "list all of the currently unused Cedar machines"]; Commander.Register[key: "FingerServer", proc: FingerServer, doc: "FingerServer on to export the RemoteFingerOps interface, FingerServer off to unexport"]; END. <> <> <> <> <> <<>> <<>>