FingerCmd.mesa
Last edited by: Donahue, February 5, 1986 11:53:10 am PST
Kornfeld, July 19, 1985 5:06:20 pm PDT
Gifford, July 22, 1985 8:54:35 am PDT
DIRECTORY
BasicTime USING [GMT, Now, Period],
Commander USING [CommandProc, Handle, Register],
Convert USING [RopeFromCard],
FingerOps,
IO,
Rope;
FingerCmd: CEDAR MONITOR
IMPORTS
BasicTime, Commander, Convert, FingerOps, IO, Rope =
BEGIN
fingerErrorCode: FingerOps.Reason;
PerformFingerAtExec: ENTRY Commander.CommandProc =
BEGIN
ENABLE
BEGIN
IO.EndOfStream => 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.STREAMIO.RIS[cmd.commandLine];
WHILE TRUE DO -- stop when command line is exhausted and IO.EndOfStream is raised
userNamePattern: Rope.ROPEIO.GetTokenRope[stream, Break].token;
fingerResult: LIST OF Rope.ROPE ← FingerOps.GetMatchingPersons[pattern: userNamePattern];
matches: CARDINAL ← 0;
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];
output results
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;
GetActiveUsers: ENTRY Commander.CommandProc = {
ENABLE FingerOps.FingerError => { fingerErrorCode ← reason; GOTO FingerProblem };
users: LIST OF Rope.ROPE = FingerOps.CurrentUsers[];
now: BasicTime.GMT = BasicTime.Now[];
twoDaysInSeconds: INT = LONG[48] * 60 * 60;
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];
IF lastChange = logout OR BasicTime.Period[from: time, to: now] > twoDaysInSeconds THEN LOOP;
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 };
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 };
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 ] };
};
Register commands with the Exec to perform finger and create an instance of the Finger Tool.
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"];
END.