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: BOOL ← TRUE;
logFSWatch: BOOL ← FALSE;
logHead, logTail: EventList ← NIL;
WatchFSLocal:
PROC [
REF
ANY]
RETURNS [
REF
ANY ←
NIL] = {
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
ANY ←
NIL] = {
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.