DIRECTORY BasicTime USING [GMT, nullGMT], DFInternal USING [Client, LocalFileInfo, RemoteFileInfo], DFOperations USING [ AbortInteraction, DFInfoInteraction, FileInteraction, InfoClass, InfoInteraction, InteractionProc, YesNoInteraction, YesNoResponse], DFUtilities USING [Date, DateToRope, RemoveVersionNumber], FS USING [ComponentPositions, Error, ErrorDesc, ExpandName, FileInfo], IO USING [PutF, PutFR, rope, STREAM], Process USING [Pause, SecondsToTicks, Ticks], Rope USING [Concat, Length, ROPE, Substr]; DFInternalImpl: CEDAR PROGRAM IMPORTS DFUtilities, FS, IO, Process, Rope EXPORTS DFInternal = BEGIN ROPE: TYPE = Rope.ROPE; retryInterval: Process.Ticks _ Process.SecondsToTicks[5]; abort: REF DFOperations.AbortInteraction _ NIL; AbortDF: PUBLIC ERROR = CODE; SimpleInteraction: PUBLIC PROC [client: DFInternal.Client, interaction: REF ANY] = { abort: BOOL; message: ROPE; DoLogging[interaction, client.log]; [abort: abort, abortMessageForLog: message] _ client.proc[interaction, client.data]; IF abort THEN { [] _ client.proc[NEW[DFOperations.InfoInteraction _ [class: $abort, message: message]], client.data]; DoAbort[client.log, message]; }; }; YesOrNo: PUBLIC PROC [client: DFInternal.Client, message: ROPE, default: BOOL, blunder: BOOL _ FALSE] RETURNS [choice: BOOL] = { response: REF ANY = DoInteraction[ client, NEW[DFOperations.YesNoInteraction _ [ message: message, blunder: blunder, default: default ]] ]; choice _ default; WITH response SELECT FROM r: REF DFOperations.YesNoResponse => choice _ r^; ENDCASE; }; DoInteraction: PUBLIC PROC [client: DFInternal.Client, interaction: REF ANY] RETURNS [response: REF ANY] = { abort: BOOL; message: ROPE; DoLogging[interaction, client.log]; [abort, message, response] _ client.proc[interaction, client.data]; IF abort THEN { [] _ client.proc[NEW[DFOperations.InfoInteraction _ [class: $abort, message: message]], client.data]; DoAbort[client.log, message]; }; }; CheckAbort: PUBLIC PROC [client: DFInternal.Client] = { SimpleInteraction[client, abort]; }; DoAbort: PUBLIC PROC [ log: IO.STREAM, message: ROPE _ NIL, proc: DFOperations.InteractionProc _ NIL, clientData: REF ANY _ NIL] = { interaction: REF ANY = NEW[DFOperations.InfoInteraction _ [class: $abort, message: message]]; IF proc # NIL AND message # NIL THEN [] _ proc[interaction, clientData]; DoLogging[interaction, log]; ERROR AbortDF }; DefaultInteractionProc: PUBLIC DFOperations.InteractionProc -- [interaction: REF ANY] RETURNS [abort: BOOL _ FALSE, abortMessageForLog: ROPE _ NIL, response: REF ANY _ NIL] -- = { WITH interaction SELECT FROM a: REF DFOperations.AbortInteraction => RETURN[abort: a.fromABORTED]; ENDCASE; }; GetFileInfo: PUBLIC PROC [ info: REF ANY, notFoundOK: BOOL _ FALSE, remoteCheck: BOOL _ FALSE, client: DFInternal.Client _ NIL, errorLevel: DFOperations.InfoClass _ $error] = { WITH info SELECT FROM local: REF DFInternal.LocalFileInfo => { date: DFUtilities.Date _ []; name: ROPE _ FS.ExpandName[local.name].fullFName; local.name _ name; IF local.date.format # $explicit THEN name _ DFUtilities.RemoveVersionNumber[name]; [fullFName: local.name, attachedTo: local.attachedTo, created: date.gmt, keep: local.keep] _ FS.FileInfo[name: name, remoteCheck: remoteCheck ! FS.Error => SELECT TRUE FROM error.group = $user AND notFoundOK => CONTINUE; RetryFSOperation[error, client] => RETRY; client # NIL => ReportFSError[error, info, client, errorLevel]; ENDCASE ]; IF date.gmt # BasicTime.nullGMT THEN date.format _ $explicit; local.date _ date; }; remote: REF DFInternal.RemoteFileInfo => { date: DFUtilities.Date _ IF remote.date.format = $explicit THEN remote.date ELSE []; name: ROPE _ remote.name; uName: ROPE _ DFUtilities.RemoveVersionNumber[name]; rName: ROPE _ NIL; gmt: BasicTime.GMT _ BasicTime.nullGMT; [fullFName: rName, created: gmt] _ FS.FileInfo[name: name, wantedCreatedTime: date.gmt, remoteCheck: TRUE ! FS.Error => SELECT TRUE FROM error.group = $user AND notFoundOK => CONTINUE; RetryFSOperation[error, client] => RETRY; client # NIL => ReportFSError[error, info, client, errorLevel]; ENDCASE ]; IF gmt # BasicTime.nullGMT AND remote.date.format = $explicit THEN { [fullFName: remote.name, created: gmt] _ FS.FileInfo[name: name, wantedCreatedTime: date.gmt, remoteCheck: TRUE ! FS.Error => SELECT TRUE FROM error.group = $user AND notFoundOK => CONTINUE; RetryFSOperation[error, client] => RETRY; client # NIL => ReportFSError[error, info, client, errorLevel]; ENDCASE ]; }; IF gmt # BasicTime.nullGMT THEN date.format _ $explicit; date.gmt _ gmt; remote.date _ date; }; ENDCASE => ERROR; }; LocalFile: PUBLIC PROC [file: ROPE] RETURNS [BOOL _ FALSE] = { RETURN[FS.ExpandName[file ! FS.Error => CONTINUE].cp.server.length = 0] }; ShortName: PUBLIC PROC [file: ROPE, keepVersion: BOOL _ FALSE] RETURNS [ROPE] = { cp: FS.ComponentPositions; l: INT; [fullFName: file, cp: cp] _ FS.ExpandName[file]; l _ (IF keepVersion THEN cp.ver.start + cp.ver.length ELSE cp.ext.start + cp.ext.length) - cp.base.start; RETURN[file.Substr[start: cp.base.start, len: l]] }; RetryFSOperation: PUBLIC PROC [error: FS.ErrorDesc, client: DFInternal.Client] RETURNS [retry: BOOL _ FALSE] = { IF error.group # $environment THEN RETURN[FALSE]; retry _ YesOrNo[client: client, message: error.explanation.Concat[". Retry?"], default: TRUE]; SELECT error.code FROM $serverInaccessible, $connectionRejected, $connectionTimedOut => Process.Pause[retryInterval]; ENDCASE; }; ReportFSError: PUBLIC PROC [ error: FS.ErrorDesc, info: REF ANY, client: DFInternal.Client, errorLevel: DFOperations.InfoClass _ $error] = { name: ROPE; WITH info SELECT FROM remote: REF DFInternal.RemoteFileInfo => name _ remote.name; local: REF DFInternal.LocalFileInfo => name _ FS.ExpandName[name _ local.name ! FS.Error => CONTINUE].fullFName; ENDCASE => ERROR; SimpleInteraction[ client, NEW[DFOperations.InfoInteraction _ [ class: errorLevel, message: IO.PutFR["%gFS.Error%g: %g", IO.rope[IF error.group = $user THEN NIL ELSE "Unexpected "], IO.rope[ IF error.explanation.Length[] = 0 THEN Rope.Concat[" manipulating ", name] ELSE NIL ], IO.rope[ IF error.explanation.Length[] # 0 THEN error.explanation ELSE "(no explanation)" ] ] ]] ]; IF errorLevel = $abort THEN DoAbort[client.log]; }; DoLogging: PROC [interaction: REF ANY, log: IO.STREAM] = { IF log = NIL THEN RETURN; WITH interaction SELECT FROM info: REF DFOperations.InfoInteraction => log.PutF["%g%g\N", IO.rope[ SELECT info.class FROM warning => "Warning: ", error => "Error: ", abort => "Abort: ", ENDCASE => NIL ], IO.rope[info.message] ]; info: REF DFOperations.DFInfoInteraction => log.PutF["%g: %g%g\N", IO.rope[ SELECT info.action FROM $start => "Start", $end => "End", $abort => "Abort", ENDCASE => NIL ], IO.rope[info.dfFile], IO.rope[IF info.message = NIL THEN NIL ELSE IO.PutFR[" (%g)", IO.rope[info.message]]] ]; file: REF DFOperations.FileInteraction => { log.PutF["%g %g %g {%g}%g\N", IO.rope[file.localFile], IO.rope[ SELECT file.action FROM $fetch => "<--", $store => "-->", $check => "<-->", ENDCASE => NIL], IO.rope[file.remoteFile], IO.rope[DFUtilities.DateToRope[[$explicit, file.date]]], IO.rope[ IF file.dateFormat = $explicit THEN NIL ELSE IO.PutFR[" ('%g')", SELECT file.dateFormat FROM $greaterThan => [character['>]], $notEqual => [rope["#"]], ENDCASE => [null[]] ] ] ]; }; ENDCASE; }; Initialize: PROC = { abort _ NEW[DFOperations.AbortInteraction _ [FALSE]]; }; Initialize[]; END. ªDFInternalImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Levin on December 16, 1983 2:05 pm Russ Atkinson, September 10, 1984 12:36:26 pm PDT Global "variables" logically, this is constant; it is set by initialization and never changed Exported to DFInternal RRA: The preferred version, regardless of the one hinted at, is the highest version number. This crock helps avoid problems with deleting elderly (but still correct) versions using Chat. Ideally our tools would play together such that this did not happen. There is a hinted version, which we should give another try at. We have found an explcit date. Internal Procedures Initialization Ê <˜šœ™Jšœ Ïmœ1™˜FJšžœžœžœ˜%Jšœžœ ˜-Jšœžœžœ ˜*—J˜šœžœž˜Jšžœžœžœ˜+Jšžœ ˜—J˜Jšž˜˜Jšžœžœžœ˜—J˜•StartOfExpansionu -- [interaction: REF ANY] RETURNS [abort: BOOL _ FALSE, abortMessageForLog: ROPE _ NIL, response: REF ANY _ NIL] -- šœ™J™Jšœ9˜9šœžœ!žœ˜/JšœJ™J——J–u -- [interaction: REF ANY] RETURNS [abort: BOOL _ FALSE, abortMessageForLog: ROPE _ NIL, response: REF ANY _ NIL] -- ™J™Jšœ™J˜Jšœ ž œžœ˜J˜š Ïnœžœžœ*žœžœ˜TJšœžœ˜ Jšœ žœ˜J˜#JšœT˜Tšžœžœ˜JšœžœQ˜eJšœ˜J˜—J˜J˜—šŸœžœžœ&žœ žœ žœžœ˜eJšžœ žœ˜šœ žœžœ˜"Jšœ˜šžœ"˜%Jšœ˜J˜Jšœ˜Jšœ˜—J˜—J˜šžœ žœž˜Jšœžœ+˜1Jšžœ˜—J˜—J˜š Ÿ œžœžœ*žœžœ˜LJšžœ žœžœ˜Jšœžœ˜ Jšœ žœ˜J˜#JšœC˜Cšžœžœ˜JšœžœQ˜eJšœ˜J˜—J˜J˜—šŸ œžœžœ ˜7Jšœ!˜!J˜—J–u -- [interaction: REF ANY] RETURNS [abort: BOOL _ FALSE, abortMessageForLog: ROPE _ NIL, response: REF ANY _ NIL] -- ˜šŸœž œ˜Jšœžœžœ˜Jš œ žœžœ'žœ žœžœžœ˜]Jšœ žœžœžœC˜]Jš žœžœžœ žœžœ$˜HJšœ˜Jšžœ˜ J˜J˜—šœžœÐcktœ˜´šžœ žœž˜Jšœžœ"žœ˜EJšžœ˜—J˜—J˜šŸ œžœžœ˜Jš œžœžœžœžœžœžœ˜DJšœžœ2˜Qšžœžœž˜šœžœ˜(Jšœ˜Jšœžœžœ"˜1Jšœ˜Jšžœžœ.˜Sšœ\˜\šžœ.˜0šœžœ ˜ šžœžœž˜Jšœžœžœ˜/Jšœ#žœ˜)Jšœ žœ3˜?Jšž˜——Jšœ˜——Jšžœžœ˜=Jšœ˜J˜—šœžœ˜*Jšœžœ žœ žœ˜TJšœžœ˜Jšœžœ)˜4Jšœžœ˜Jšœ'˜'J˜JšÏc™šœ"˜"šžœ@ž˜Fšœžœ ˜ šžœžœž˜Jšœžœžœ˜/Jšœ#žœ˜)Jšœ žœ3˜?Jšž˜——Jšœ˜——šžœžœ žœ˜DJšœ?™?šœ(˜(šžœ@ž˜Fšœžœ ˜ šžœžœž˜Jšœžœžœ˜/Jšœ#žœ˜)Jšœ žœ3˜?Jšž˜——Jšœ˜——J˜—J˜šžœž˜Jšœ™Jšœ˜J˜—J˜Jšœ˜J˜—Jšžœžœ˜—J˜—J˜šŸ œžœžœžœžœžœžœ˜>Jšžœžœžœ žœ˜GJ˜—J˜šŸ œžœžœžœ žœžœžœžœ˜QJšœžœ˜Jšœžœ˜Jšœžœ˜0Jšœžœ žœžœ/˜iJšžœ,˜2J˜—J˜šŸœžœžœ žœ&˜NJšžœ žœžœ˜!Jšžœžœžœžœ˜1JšœYžœ˜_šžœ ž˜šœ@˜@Jšœ˜—Jšžœ˜—J˜—J˜šŸ œžœžœ˜JšœžœžœžœM˜oJšœžœ˜ šžœžœž˜Jšœžœ1˜<šœžœ˜&Jšœžœ žœ žœ ˜I—Jšžœžœ˜—šœ˜Jšœ˜šžœ!˜$Jšœ˜šœ ˜ šžœ˜Jš žœžœžœžœžœ˜<šžœ˜Jšžœ žœ$˜JJšžœž˜J˜—šžœ˜Jšžœ žœ˜8Jšžœ˜J˜—J˜——J˜—Jšœ˜—Jšžœžœ˜0J˜—J™J™J˜š Ÿ œžœžœžœžœžœ˜:Jšžœžœžœžœ˜šžœ žœž˜šœžœ ˜)šœ˜šžœ˜šžœ ž˜Jšœ@žœž˜N—Jšœ˜—Jšžœ˜J˜——šœžœ"˜+šœ˜šžœ˜šžœ ž˜Jšœ5žœž˜C—Jšœ˜—Jšžœ˜Jšžœžœžœžœžœžœžœ˜UJšœ˜——šœžœ"˜+˜Jšžœ˜šžœ˜šžœ ž˜Jšœ4žœžœ˜D——Jšžœ˜Jšžœ6˜8šžœ˜Jšžœžœž˜'šžœžœ˜šžœž˜Jšœ ˜ Jšœ˜Jšžœ ˜—Jšœ˜—J˜—Jšœ˜—J˜—Jšžœ˜—J˜—J˜J™J–u -- [interaction: REF ANY] RETURNS [abort: BOOL _ FALSE, abortMessageForLog: ROPE _ NIL, response: REF ANY _ NIL] -- ˜šŸ œžœ˜Jšœžœ"žœ˜5J˜J˜—J˜ J˜Jšžœ˜J˜J˜J˜—…—+î