MakeDoFiles.Mesa
Last Edited by: Spreitzer, February 20, 1986 10:01:12 pm PST
DIRECTORY Basics, BasicTime, CedarProcess, Convert, FS, FSBackdoor, IO, MakeDo, PrincOpsUtils, Process, RedBlackTree, Rope, UserProfile, ViewerClasses, ViewerIO;
MakeDoFiles: CEDAR MONITOR
IMPORTS BasicTime, CedarProcess, Convert, FS, FSBackdoor, IO, MakeDo, Rope, UserProfile
EXPORTS MakeDo
=
BEGIN OPEN MakeDo;
fileClass: PUBLIC NodeClass ← DeclareNodeClass[
name: "file",
CanonizeName: CannonizeFileName,
GetTime: GetFileTime
];
CannonizeFileName: PROC [random: ROPE] RETURNS [canonical: ROPE] = {
full: ROPE;
cp: FS.ComponentPositions;
[full, cp] ← FS.ExpandName[random];
canonical ← full.Substr[len: cp.ext.start + cp.ext.length];
};
GetFileTime: PUBLIC PROC [n: Node] RETURNS [created: Time] --GetTimeProc-- =
BEGIN
name: ROPE = n.PublicPartsOfNode[].name;
FileViewerOps.WaitUntilSaved[fileName: n.name, feedBack: GetCommanderHandle[].err];
[created: created] ← FS.FileInfo[name !FS.Error =>
{created ← notExistTime; CONTINUE}];
END;
localOpNames: ARRAY FSBackdoor.CreateOp OF ATOM = [
writeClose: $writeClose,
renameTo: $renameTo,
copyTo: $copyTo
];
remoteOpNames: ARRAY FSBackdoor.RemoteOp OF ATOM = [
startRetrieving: $startRetrieving,
endRetrieving: $endRetrieving,
startStoring: $startStoring,
endStoring: $endStoring,
startDeleting: $startDeleting,
endDeleting: $endDeleting,
startRenaming: $startRenaming,
endRenaming: $endRenaming,
startFlushing: $startFlushing,
endFlushing: $endFlushing
];
EventList: TYPE = LIST OF Event;
Event: TYPE = RECORD [
start, finish: BasicTime.GMT ← BasicTime.nullGMT,
local: BOOL,
op: ATOM,
fName: ROPE];
fsWatchEnabled: BOOLTRUE;
logFSWatch: BOOLFALSE;
logHead, logTail: EventList ← NIL;
WatchFSLocal: PROC [REF ANY] RETURNS [REF ANYNIL] = {
ce: REF READONLY FSBackdoor.CreateEvent ← NIL;
WHILE fsWatchEnabled DO
me: EventList ← NIL;
ce ← FSBackdoor.NextCreateEvent[ce];
IF logFSWatch THEN me ← Log[[
start: BasicTime.Now[],
local: TRUE,
op: localOpNames[ce.op],
fName: ce.fName]];
{ENABLE ABORTED => CONTINUE;
n: Node ← GetNode[ce.fName, fileClass, FALSE];
IF n # NIL THEN {
SuspectNodeChange[n];
};
};
IF me#NIL THEN me.first.finish ← BasicTime.Now[];
ENDLOOP;
ce ← ce;
};
WatchFSRemote: PROC [REF ANY] RETURNS [REF ANYNIL] = {
re: REF READONLY FSBackdoor.RemoteEvent ← NIL;
WHILE fsWatchEnabled DO
me: EventList ← NIL;
re ← FSBackdoor.NextRemoteEvent[re];
IF logFSWatch THEN me ← Log[[
start: BasicTime.Now[],
local: FALSE,
op: remoteOpNames[re.op],
fName: re.fName]];
{ENABLE ABORTED => CONTINUE;
n: Node ← GetNode[re.fName, fileClass, FALSE];
IF n # NIL THEN {
SuspectNodeChange[n];
};
};
IF me#NIL THEN me.first.finish ← BasicTime.Now[];
ENDLOOP;
re ← re;
};
localWatcher, remoteWatcher: CedarProcess.Process;
Log: ENTRY PROC [e: Event] RETURNS [el: EventList] = {
ENABLE UNWIND => NULL;
el ← LIST[e];
IF logTail = NIL THEN logHead ← el ELSE logTail.rest ← el;
logTail ← el;
};
PrintLog: PROC [to: IO.STREAM] = {
FOR log: EventList ← logHead, log.rest WHILE log # NIL DO
to.PutF[
"%g-%g: %g[%g]\n",
[rope[Convert.RopeFromTime[from: log.first.start, start: days, end: seconds, useAMPM: FALSE, includeZone: FALSE]]],
[rope[Convert.RopeFromTime[from: log.first.finish, start: hours, end: seconds, useAMPM: FALSE, includeZone: FALSE]]],
[atom[log.first.op]],
[rope[log.first.fName]]];
ENDLOOP;
};
NoteProfile: PROC [reason: UserProfile.ProfileChangeReason] --UserProfile.ProfileChangedProc-- = {
logFSWatch ← UserProfile.Boolean["MakeDo.LogFSWatch", FALSE];
};
Start: PROC = {
UserProfile.CallWhenProfileChanges[NoteProfile];
localWatcher ← CedarProcess.Fork[action: WatchFSLocal, options: [inheritProperties: TRUE]];
remoteWatcher ← CedarProcess.Fork[action: WatchFSRemote, options: [inheritProperties: TRUE]];
};
Start[];
END.