DIRECTORY Booting USING [RegisterProcs, RollbackProc], FS USING [Error, StreamOpen], IO USING [Close, GetChar, GetLength, PutRope, STREAM], MessageWindow USING [Append], Process USING [Detach], Rope USING [Concat, Equal, Fetch, Find, FromProc, ROPE, Size, Substr], UserCredentials USING [Get], ViewerEvents USING [EventProc, RegisterEventProc, UnRegisterEventProc]; MaintainFilesList: CEDAR MONITOR IMPORTS Booting, FS, IO, Process, Rope, MessageWindow, UserCredentials, ViewerEvents = { STREAM: TYPE = IO.STREAM; regProc: REF; filesList: Rope.ROPE; userName: Rope.ROPE = UserName[]; fileName: Rope.ROPE = Rope.Concat[userName, ".List"]; UserName: PROC RETURNS [name: Rope.ROPE] = { dot: INT; name _ UserCredentials.Get[].name; dot _ Rope.Find[name, "."]; IF dot > 0 THEN name _ Rope.Substr[name, 0, dot]; }; Add: ViewerEvents.EventProc = TRUSTED { Process.Detach[FORK AddToFilesList[viewer.file]] }; AddToFilesList: ENTRY PROC [name: Rope.ROPE] = { ENABLE UNWIND => NULL; s: STREAM _ NIL; AlreadyThere: PROC RETURNS [BOOL] = { pos: INT _ 0; len: INT = Rope.Size[name]; fileLen: INT = Rope.Size[filesList]; blank: CHAR = ' ; WHILE (pos _ Rope.Find[filesList, name, pos, FALSE]) # -1 DO -- look for adjacent blanks IF (pos>0 AND Rope.Fetch[filesList, pos-1] # blank) OR (pos+len < fileLen AND Rope.Fetch[filesList, pos+len] # blank) THEN { pos _ pos+len; LOOP }; RETURN [TRUE]; ENDLOOP; RETURN [FALSE] }; IF Rope.Size[name]=0 THEN RETURN; IF Rope.Equal[name, fileName, FALSE] THEN { GetFilesList[]; RETURN; }; IF AlreadyThere[] THEN RETURN; MessageWindow.Append["Adding ", TRUE]; MessageWindow.Append[name]; MessageWindow.Append[" to "]; MessageWindow.Append[fileName]; filesList _ Rope.Concat[filesList, Rope.Concat[" ", name]]; s _ FS.StreamOpen[fileName, $create]; IO.PutRope[s, filesList]; IO.Close[s]; }; AfterRollback: Booting.RollbackProc = { --update cached copy-- GetFilesList[]; }; GetFilesList: PROC = { s: IO.STREAM = FS.StreamOpen[fileName, $read ! FS.Error => GO TO Quit]; len: INT = IO.GetLength[s]; readChar: SAFE PROC RETURNS [CHAR] = { RETURN [IO.GetChar[s]] }; filesList _ Rope.FromProc[len, readChar]; IO.Close[s]; EXITS Quit => filesList _ NIL; }; UnReg: ENTRY PROC = { ENABLE UNWIND => NULL; IF regProc # NIL THEN ViewerEvents.UnRegisterEventProc[regProc, save]; regProc _ NIL; filesList _ NIL }; Reg: ENTRY PROC = { ENABLE UNWIND => NULL; IF regProc # NIL THEN ViewerEvents.UnRegisterEventProc[regProc, save]; regProc _ ViewerEvents.RegisterEventProc[Add, save]; GetFilesList[] }; Reg[]; Booting.RegisterProcs[r: AfterRollback]; }... üMaintainFilesList.mesa Paxton, August 31, 1982 4:16 pm McGregor, September 10, 1982 2:21 pm Maxwell, January 6, 1983 12:19 pm Russ Atkinson, September 26, 1983 6:03 pm Doug Wyatt, January 13, 1984 4:02 pm record hand change to file holding list Ę˜šĎc™Jš™Jš$™$J™!J™)J™$J™—šĎk ˜ Jšœžœ˜,Jšžœžœ˜Jšžœžœ&žœ˜6Jšœžœ ˜Jšœžœ ˜Jšœžœ(žœ˜FJšœžœ˜Jšœ žœ5˜GJ˜—J˜Jšœž ˜ Jšžœ žœžœ=˜TJšœ˜J˜Jšžœžœžœžœ˜J˜Jšœ žœ˜ Jšœžœ˜Jšœžœ˜!Jšœžœ"˜5J˜šĎnœžœžœ žœ˜,Jšœžœ˜ Jšœ"˜"J˜Jšžœ žœ"˜1Jšœ˜J˜—Jšœžœžœ ˜[J˜šŸœžœžœ žœ˜0Jšžœžœžœ˜Jšœžœžœ˜šŸ œžœžœžœ˜%Jšœžœ˜ Jšœžœ˜Jšœ žœ˜$Jšœžœ˜šžœ(žœžœ˜Xšžœžœ'ž˜6Jšœžœ(˜>Jšžœžœ˜—Jšžœžœ˜Jšžœ˜—Jšžœžœ˜—Jšžœžœžœ˜!šžœžœžœ˜+Jšœ'™'Jšœ˜Jšžœ˜Jšœ˜—Jšžœžœžœ˜Jšœ žœ˜&J˜J˜J˜J˜;Jšœ%˜%Jšžœ˜Jšžœ ˜ J˜J˜—šŸ œ˜'Jšœ˜Jšœ˜Jšœ˜J˜—šŸ œžœ˜Jš œžœžœžœžœ žœžœ˜GJšœžœžœ˜Jš œ žœžœžœžœžœžœ˜@J˜)Jšžœ ˜ Jšžœžœ˜J˜J˜—šŸœžœžœ˜Jšžœžœžœ˜Jšžœ žœžœ1˜FJšœ žœ˜Jšœ žœ˜J˜—šŸœžœžœ˜Jšžœžœžœ˜Jšžœ žœžœ1˜FJ˜4J˜J˜—J˜Jšœ(˜(J˜J˜—…—