DIRECTORY AlpFile, AlpineEnvironment, AlpineFile, AlpDirectory, AlpDirectoryExtras, AlpInstance, AlpTransaction, BasicTime, Buttons, IO, Rope, ViewerClasses, ViewerTools, YodelData; YodelPropertiesImpl: CEDAR PROGRAM IMPORTS AlpDirectory, AlpDirectoryExtras, AlpFile, AlpInstance, AlpTransaction, IO, Rope, ViewerTools, YodelData EXPORTS YodelData = BEGIN OPEN YodelData; ROPE: TYPE = Rope.ROPE; accessListToCommaROPE: PROC [accessList: AlpineEnvironment.AccessList] RETURNS [resultRope: ROPE _ NIL] = { IF accessList = NIL THEN resultRope _ Rope.Concat[resultRope,"*none*"] ELSE { UNTIL accessList = NIL DO accessItem: AlpineEnvironment.RName _ accessList.first; resultRope _ Rope.Concat[resultRope,accessItem]; accessList _ accessList.rest; IF accessList # NIL THEN resultRope _ Rope.Concat[resultRope,", "]; ENDLOOP; } }; ExamineFile: PUBLIC PROC [trans: AlpTransaction.Handle, server: ROPE, directory: ROPE, file: ROPE, user: ROPE _ NIL, password: ROPE _ NIL , displayProperties: AlpineFile.PropertySet _ AlpineFile.allProperties, d: MyData] RETURNS [LIST OF REF ANY] = { fullFileName: ROPE; properties: LIST OF AlpineEnvironment.PropertyValuePair; resultRope: ROPE _ NIL; fileHandle: AlpFile.Handle; outcome: AlpTransaction.Outcome; failureName: ROPE _ "" ; readLockOption: AlpFile.LockOption = [read, IF d.breakLocks THEN wait ELSE fail]; { ENABLE UNWIND => IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort]; IF trans = NIL THEN GOTO notAlpineFile; IF d.assertWheel THEN trans.AssertAlpineWheel[TRUE]; fullFileName _ Rope.Concat["[",Rope.Concat[server,Rope.Concat["]", Rope.Concat[directory,file]]]]; [fileHandle, ] _ AlpDirectory.OpenFile[ transHandle: trans, access: readOnly, lock: readLockOption, name: fullFileName, createOptions: oldOnly]; properties _ AlpFile.ReadProperties[handle: fileHandle, lock: readLockOption ! AlpInstance.LockFailed => GOTO lockError; ]; { size: INT; size _ fileHandle.GetSize[]; ViewerTools.SetContents[viewer: d.oSize, contents: IO.PutFR["%g", IO.int[size]], paint: FALSE]; }; { keep: CARDINAL; [keep: keep] _ AlpDirectoryExtras.GetKeep[fileName: fullFileName, transHandle: trans]; ViewerTools.SetContents[viewer: d.oFileKeep, contents: IO.PutFR["%g", IO.card[keep]], paint: FALSE]; }; UNTIL properties = NIL DO property: AlpineEnvironment.PropertyValuePair _ properties.first ; properties _ properties.rest; BEGIN SELECT property.property FROM byteLength => { byteLength: INT _ NARROW[property, AlpineEnvironment.PropertyValuePair.byteLength].byteLength; ViewerTools.SetContents[viewer: d.oByteLength, contents: IO.PutFR["%g", IO.int[byteLength]], paint: FALSE]; }; createTime => { createTime: BasicTime.GMT _ NARROW[property, AlpineEnvironment.PropertyValuePair.createTime].createTime; }; highWaterMark => { highWaterMark: AlpineEnvironment.PageCount _ NARROW[property, AlpineEnvironment.PropertyValuePair.highWaterMark].highWaterMark; ViewerTools.SetContents[viewer: d.oHighWaterMark, contents: IO.PutFR["%g", IO.int[highWaterMark]], paint: FALSE]; }; modifyAccess => { modifyAccess: AlpineEnvironment.AccessList _ NARROW[property, AlpineEnvironment.PropertyValuePair.modifyAccess].modifyAccess; resultRope _ accessListToCommaROPE[modifyAccess]; ViewerTools.SetContents[viewer: d.oModifyAccess, contents: resultRope, paint: FALSE]; }; owner => { owner: AlpineEnvironment.OwnerName _ NARROW[property, AlpineEnvironment.PropertyValuePair.owner].owner; ViewerTools.SetContents[viewer: d.oOwner, contents: IO.PutFR["%g", IO.rope[owner]], paint: FALSE]; }; readAccess => { readAccess: AlpineEnvironment.AccessList _ NARROW[property, AlpineEnvironment.PropertyValuePair.readAccess].readAccess; resultRope _ accessListToCommaROPE[readAccess] ; ViewerTools.SetContents[viewer: d.oReadAccess, contents: resultRope, paint: FALSE]; }; stringName => { stringName: ROPE _ NARROW[property, AlpineEnvironment.PropertyValuePair.stringName].stringName; ViewerTools.SetContents[viewer: d.oStringName, contents: IO.PutFR["%g", IO.rope[stringName]], paint: FALSE]; }; version => { version: AlpineEnvironment.FileVersion _ NARROW[property, AlpineEnvironment.PropertyValuePair.version].version; ViewerTools.SetContents[viewer: d.oVersion, contents: IO.PutFR["%g", IO.int[version]], paint: FALSE]; }; ENDCASE; END; ENDLOOP; outcome _ AlpTransaction.Finish[trans, commit]; RETURN [CONS[NARROW["Examine of file successful ",ROPE],NIL]]; EXITS lockError => { outcome _ AlpTransaction.Finish[trans, abort]; ViewerTools.SetContents[viewer: d.oByteLength, contents: "", paint: FALSE]; ViewerTools.SetContents[viewer: d.oHighWaterMark, contents: "", paint: FALSE]; ViewerTools.SetContents[viewer: d.oModifyAccess, contents: "", paint: FALSE]; ViewerTools.SetContents[viewer: d.oOwner, contents: "", paint: FALSE]; ViewerTools.SetContents[viewer: d.oReadAccess, contents: "", paint: FALSE]; ViewerTools.SetContents[viewer: d.oStringName, contents: "", paint: FALSE]; RETURN[CONS[ NARROW["lock prevents access to file",ROPE] ,NIL]]; }; notAlpineFile => { RETURN[CONS[ NARROW["Cannot Examine a non-Alpine file",ROPE] ,NIL]]; }; }; }; ExamineProc: PUBLIC Buttons.ButtonProc = { resultList: LIST OF REF ANY _ NIL; d: MyData = NARROW[clientData]; p: ViewerClasses.Viewer = NARROW[parent]; server, user, file, password: ROPE; directory, restOfPattern: ROPE; parseError: BOOL; errorExplanation: ROPE; bangPos: INT; callExamine: YodelData.PerformProc = { RETURN[ExamineFile[trans, server, directory, restOfPattern, user, password, d.displayProperties, d]]; }; typeParseError: PROC [] = { d.out.PutF["\nBad name in Examine because %g\n", IO.rope[errorExplanation]]; }; d.stopFlag _ FALSE; [user, password, server, directory, file, parseError, errorExplanation] _ ParseSArgs[d]; IF parseError THEN { typeParseError[]; GOTO badParse;}; [directory, restOfPattern] _ DecomposePattern[server: server, pattern: file, user: user]; bangPos _ Rope.Find[restOfPattern, "!"]; IF bangPos < 0 THEN restOfPattern _ restOfPattern.Cat["!H"]; d.out.PutF["\nExamine of [%g]%g%g\n", IO.rope[server], IO.rope[directory], IO.rope[restOfPattern]]; resultList _ PerformOp[performProc: callExamine, server: server, user: user, password: password]; DO nowRope: ROPE _ NARROW[IF resultList = NIL THEN NIL ELSE resultList.first]; IF resultList = NIL THEN EXIT; resultList _ resultList.rest; d.out.PutF[" %g\n", IO.rope[nowRope]]; ENDLOOP; CreateButtons[d, p.parent.parent]; EXITS badParse => {}; }; getAccessList: PROC [stream: IO.STREAM] RETURNS [outList: AlpineEnvironment.AccessList _ NIL] = { UNTIL IO.EndOf[stream] DO { token: ROPE _ IO.GetTokenRope[stream, IO.IDProc ! IO.EndOfStream => GOTO endList].token; IF (token # NIL) AND Rope.Fetch[token] # ', THEN outList _ CONS[NARROW[token, AlpineEnvironment.RName], outList]; }; ENDLOOP; EXITS endList => RETURN; }; ApplyToFile: PUBLIC PROC [trans: AlpTransaction.Handle, server: ROPE, directory: ROPE, file: ROPE, user: ROPE _ NIL, password: ROPE _ NIL , displayProperties: AlpineFile.PropertySet _ AlpineFile.allProperties, d: MyData] RETURNS [LIST OF REF ANY] = { fullFileName: ROPE; newProperties: LIST OF AlpineEnvironment.PropertyValuePair _ NIL ; properties: LIST OF AlpineEnvironment.PropertyValuePair; resultRope: ROPE _ NIL; fileHandle: AlpFile.Handle; outcome: AlpTransaction.Outcome; scratchStream: IO.STREAM _ NIL; failureName: ROPE _ "" ; readLockOption: AlpFile.LockOption = [read, IF d.breakLocks THEN wait ELSE fail]; writeLockOption: AlpFile.LockOption = [write, IF d.breakLocks THEN wait ELSE fail]; { ENABLE UNWIND => IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort]; IF trans = NIL THEN GOTO notAlpineFile; IF d.assertWheel THEN trans.AssertAlpineWheel[TRUE]; fullFileName _ Rope.Concat["[",Rope.Concat[server,Rope.Concat["]", Rope.Concat[directory,file]]]]; [fileHandle, ] _ AlpDirectory.OpenFile[ transHandle: trans, name: fullFileName, access: readWrite, lock: writeLockOption, createOptions: oldOnly]; properties _ AlpFile.ReadProperties[handle: fileHandle, lock: readLockOption ! AlpInstance.LockFailed => GOTO lockError]; { newSizeRope: ROPE; newSize: INT; size: INT; size _ fileHandle.GetSize[]; newSizeRope _ ViewerTools.GetContents[viewer: d.oSize]; scratchStream _ IO.RIS[newSizeRope, scratchStream]; newSize _ NARROW[IO.GetInt[scratchStream]] ; fileHandle.SetSize[newSize]; }; { newKeepRope: ROPE; newKeep: LONG CARDINAL; newKeepRope _ ViewerTools.GetContents[viewer: d.oFileKeep]; scratchStream _ IO.RIS[newKeepRope, scratchStream]; newKeep _ NARROW[IO.GetCard[scratchStream]] ; [] _ AlpDirectory.SetKeep[fileName: fullFileName, transHandle: trans, keep: newKeep]; }; UNTIL properties = NIL DO property: AlpineEnvironment.PropertyValuePair _ properties.first ; properties _ properties.rest; { SELECT property.property FROM byteLength => { newByteLengthRope: ROPE; newByteLength: INT ; byteLength: INT _ NARROW[property, AlpineEnvironment.PropertyValuePair.byteLength].byteLength; newByteLengthRope _ ViewerTools.GetContents[viewer: d.oByteLength]; scratchStream _ IO.RIS[newByteLengthRope, scratchStream]; newByteLength _ IO.GetInt[scratchStream] ; newProperties _ CONS[[byteLength[newByteLength]], newProperties]; }; highWaterMark => { newHighWaterMark: INT ; newHighWaterMarkRope: ROPE _ ViewerTools.GetContents[viewer: d.oHighWaterMark]; scratchStream _ IO.RIS[newHighWaterMarkRope, scratchStream]; newHighWaterMark _ NARROW[IO.GetInt[scratchStream]] ; newProperties _ CONS[[highWaterMark[newHighWaterMark]], newProperties]; }; modifyAccess => { newModifyAccess: AlpineEnvironment.AccessList _ NIL ; newModifyAccessRope: ROPE _ ViewerTools.GetContents[viewer: d.oModifyAccess]; scratchStream _ IO.RIS[newModifyAccessRope, scratchStream]; newModifyAccess _ getAccessList[scratchStream]; newProperties _ CONS[[modifyAccess[newModifyAccess]], newProperties]; }; owner => { newOwnerRope: ROPE; newOwner: ROPE; newOwnerRope _ ViewerTools.GetContents[viewer: d.oOwner]; newOwner _ NARROW[newOwnerRope]; newProperties _ CONS[[owner[newOwner]], newProperties]; }; readAccess => { newReadAccess: AlpineEnvironment.AccessList _ NIL ; newReadAccessRope: ROPE _ ViewerTools.GetContents[viewer: d.oReadAccess]; scratchStream _ IO.RIS[newReadAccessRope, scratchStream]; newReadAccess _ getAccessList[scratchStream]; newProperties _ CONS[[readAccess[newReadAccess]], newProperties]; }; stringName => { newStringName: AlpineEnvironment.String; newStringNameRope: ROPE _ ViewerTools.GetContents[viewer: d.oStringName]; newStringName _ NARROW[newStringNameRope]; newProperties _ CONS[[stringName[newStringName]], newProperties]; }; ENDCASE; }; ENDLOOP; AlpFile.WriteProperties[handle: fileHandle, properties: newProperties, lock: writeLockOption ! AlpInstance.LockFailed => GOTO lockError]; outcome _ AlpTransaction.Finish[trans, commit]; RETURN [CONS[NARROW["Apply properties to file successful ",ROPE],NIL]]; EXITS lockError => { outcome _ AlpTransaction.Finish[trans, abort]; ViewerTools.SetContents[viewer: d.oByteLength, contents: "", paint: FALSE]; ViewerTools.SetContents[viewer: d.oHighWaterMark, contents: "", paint: FALSE]; ViewerTools.SetContents[viewer: d.oModifyAccess, contents: "", paint: FALSE]; ViewerTools.SetContents[viewer: d.oOwner, contents: "", paint: FALSE]; ViewerTools.SetContents[viewer: d.oReadAccess, contents: "", paint: FALSE]; ViewerTools.SetContents[viewer: d.oStringName, contents: "", paint: FALSE]; RETURN[CONS[ NARROW["lock prevents access to file",ROPE], NIL]]; }; notAlpineFile => { RETURN[CONS[ NARROW["Cannot Apply to a non-Alpine file",ROPE], NIL]]; }; }; }; ApplyProc: PUBLIC Buttons.ButtonProc= { resultList: LIST OF REF ANY _ NIL; d: MyData = NARROW[clientData]; p: ViewerClasses.Viewer = NARROW[parent]; server, user, file, password: ROPE; directory, restOfPattern: ROPE; parseError: BOOL; errorExplanation: ROPE; callApply: YodelData.PerformProc = { RETURN[ApplyToFile[trans, server, directory, restOfPattern, user, password, d.displayProperties, d]]; }; typeParseError: PROC [] = { d.out.PutF["\nBad pattern in Apply because %g\n", IO.rope[errorExplanation]]; }; d.stopFlag _ FALSE; [user, password, server, directory, file, parseError, errorExplanation] _ ParseSArgs[d]; IF parseError THEN { typeParseError[]; GOTO badParse;}; [directory, restOfPattern] _ DecomposePattern[server:server, pattern: file, user: user]; d.out.PutF["\nApply changes to [%g]%g%g\n", IO.rope[server], IO.rope[directory], IO.rope[restOfPattern]]; resultList _ PerformOp[performProc: callApply, server: server, user: user, password: password]; DO nowRope: ROPE _ NARROW[IF resultList = NIL THEN NIL ELSE resultList.first]; IF resultList = NIL THEN EXIT; resultList _ resultList.rest; d.out.PutF[" %g\n", IO.rope[nowRope]]; ENDLOOP; CreateButtons[d, p.parent.parent]; EXITS badParse => {}; }; ReadQuota: PUBLIC PROC [trans: AlpTransaction.Handle, server: ROPE, directory: ROPE, user: ROPE _ NIL, password: ROPE _ NIL , d: MyData] RETURNS [LIST OF REF ANY] = { resultList: LIST OF REF ANY _ NIL; resultRope: ROPE _ NIL; outcome: AlpTransaction.Outcome; properties: LIST OF AlpineEnvironment.OwnerPropertyValuePair; pageLimit, spaceInUse: AlpineEnvironment.PageCount; failureName: ROPE _ "" ; IF trans = NIL THEN GOTO notAlpineFile; IF d.assertWheel THEN trans.AssertAlpineWheel[TRUE]; properties _ AlpTransaction.ReadOwnerProperties[ handle: trans, volumeGroupID: AlpTransaction.GetNextVolumeGroup[handle: trans, previousGroup: AlpineEnvironment.nullVolumeGroupID, lock: [none, fail]], owner: directory, desiredProperties: [quota: TRUE, spaceInUse: TRUE]]; outcome _ AlpTransaction.Finish[trans, commit]; UNTIL properties = NIL DO -- because ReadOwnerProperties does not sort them yet ... WITH properties.first SELECT FROM q: AlpineEnvironment.OwnerPropertyValuePair.quota => pageLimit _ q.quota; s: AlpineEnvironment.OwnerPropertyValuePair.spaceInUse => spaceInUse _ s.spaceInUse; ENDCASE ; properties _ properties.rest; ENDLOOP; RETURN [CONS[NARROW[ IO.PutFR["Page Limit is %g and Space in Use is %g", IO.int[pageLimit], IO.int[spaceInUse]],ROPE] ,NIL]]; EXITS notAlpineFile => { RETURN[CONS[ NARROW["Cannot get the quota for a non-Alpine server",ROPE], NIL]]; }; }; QuotaProc: PUBLIC Buttons.ButtonProc = { result: ROPE; resultList: LIST OF REF ANY _ NIL; d: MyData = NARROW[clientData]; server, user, file, password: ROPE; directory: ROPE; parseError: BOOL; errorExplanation: ROPE; callQuota: YodelData.PerformProc = { RETURN[ReadQuota[trans, server, directory.Substr[start: 1, len: directory.Size[]-2], user, password, d]] }; typeParseError: PROC [] = { d.out.PutF["\nBad name in Quota because %g\n", IO.rope[errorExplanation]]; }; [user, password, server, directory, file, parseError, errorExplanation] _ ParseSArgs[d]; IF parseError THEN { typeParseError[]; GOTO badParse;}; d.out.PutF["\nQuota for [%g]%g\n", IO.rope[server], IO.rope[directory]]; resultList _ PerformOp[performProc: callQuota, server: server, user: user, password: password ]; result _ NARROW[IF resultList = NIL THEN NIL ELSE resultList.first]; d.out.PutF[" %g\n", IO.rope[result]]; EXITS badParse => {}; }; GetOwnerProperties: PUBLIC PROC [trans: AlpTransaction.Handle, server: ROPE, directory: ROPE, user: ROPE _ NIL, password: ROPE _ NIL , d: MyData] RETURNS [LIST OF REF ANY] = { resultList: LIST OF REF ANY _ NIL; resultRope: ROPE _ NIL; outcome: AlpTransaction.Outcome; properties: LIST OF AlpineEnvironment.OwnerPropertyValuePair; rootProperties: LIST OF AlpineEnvironment.PropertyValuePair; failureName: ROPE _ "" ; rootFile: AlpineEnvironment.UniversalFile _ AlpineEnvironment.nullUniversalFile ; fileHandle: AlpFile.Handle; { ENABLE UNWIND => IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort]; IF trans = NIL THEN GOTO notAlpineFile; IF d.assertWheel THEN trans.AssertAlpineWheel[TRUE]; { keep: CARDINAL; keep _ AlpDirectoryExtras.GetDefaultKeep[volume: server, owner: directory, transHandle: trans]; ViewerTools.SetContents[viewer: d.oOwnerKeep, contents: IO.PutFR["%g", IO.card[keep]], paint: FALSE]; }; properties _ AlpTransaction.ReadOwnerProperties[handle: trans, volumeGroupID: AlpTransaction.GetNextVolumeGroup[handle: trans, previousGroup: AlpineEnvironment.nullVolumeGroupID, lock: [none, fail]], owner: directory]; UNTIL properties = NIL DO -- because ReadOwnerProperties does not sort them yet ... WITH properties.first SELECT FROM q: AlpineEnvironment.OwnerPropertyValuePair.createAccessList => { createList: AlpineEnvironment.AccessList _ q.createAccessList; resultRope: ROPE _ accessListToCommaROPE[createList]; ViewerTools.SetContents[viewer: d.oCreateAccessList, contents: resultRope, paint: FALSE]; }; s: AlpineEnvironment.OwnerPropertyValuePair.modifyAccessList => { modifyList: AlpineEnvironment.AccessList _ s.modifyAccessList; }; r: AlpineEnvironment.OwnerPropertyValuePair.rootFile => { rootFile _ r.rootFile ; }; t: AlpineEnvironment.OwnerPropertyValuePair.quota => {}; u: AlpineEnvironment.OwnerPropertyValuePair.spaceInUse => {}; ENDCASE ; properties _ properties.rest; ENDLOOP; IF rootFile = AlpineEnvironment.nullUniversalFile THEN { RETURN [CONS[NARROW[ "Could not find root file on owner property list",ROPE] ,NIL]]; }; [fileHandle]_ AlpFile.Open[transHandle: trans, universalFile: rootFile, access: readOnly, lock: [read, fail]]; rootProperties _ AlpFile.ReadProperties[handle: fileHandle, lock: [read, fail] ! AlpInstance.LockFailed => GOTO lockError]; UNTIL rootProperties = NIL DO property: AlpineEnvironment.PropertyValuePair _ rootProperties.first ; SELECT property.property FROM modifyAccess => { modifyAccess: AlpineEnvironment.AccessList _ NARROW[property, AlpineEnvironment.PropertyValuePair.modifyAccess].modifyAccess; resultRope _ accessListToCommaROPE[modifyAccess]; ViewerTools.SetContents[viewer: d.oRootModifyAccess, contents: resultRope, paint: FALSE]; }; readAccess => { readAccess: AlpineEnvironment.AccessList _ NARROW[property, AlpineEnvironment.PropertyValuePair.readAccess].readAccess; resultRope _ accessListToCommaROPE[readAccess]; ViewerTools.SetContents[viewer: d.oRootReadAccess, contents: resultRope, paint: FALSE]; }; ENDCASE; rootProperties _ rootProperties.rest; ENDLOOP; outcome _ AlpTransaction.Finish[trans, commit]; RETURN [CONS[NARROW[ "Owner Properties access successful",ROPE] ,NIL]]; EXITS notAlpineFile => { RETURN[CONS[NARROW["Cannot get owner properties for a non-Alpine server",ROPE], NIL]]; }; lockError => { RETURN[CONS[NARROW["Lock prevents access to root file",ROPE], NIL]]; }; }; }; GetOwnerPropertiesProc: PUBLIC Buttons.ButtonProc = { resultList: LIST OF REF ANY _ NIL; d: MyData = NARROW[clientData]; p: ViewerClasses.Viewer = NARROW[parent]; server, user, file, password: ROPE; directory: ROPE; parseError: BOOL; errorExplanation: ROPE; callGet: YodelData.PerformProc = { RETURN[GetOwnerProperties[trans, server, directory.Substr[start: 1, len: directory.Size[]-2], user, password, d]] }; typeParseError: PROC [] = { d.out.PutF["\nBad pattern in Get Owner Properties because %g\n", IO.rope[errorExplanation]]; }; d.stopFlag _ FALSE; [user, password, server, directory, file, parseError, errorExplanation] _ ParseSArgs[d]; IF parseError THEN { typeParseError[]; GOTO badParse;}; d.out.PutF["\nGet Properties for [%g]%g\n", IO.rope[server], IO.rope[directory]]; resultList _ PerformOp[performProc: callGet, server: server, user: user, password: password]; DO nowRope: ROPE _ NARROW[IF resultList = NIL THEN NIL ELSE resultList.first]; IF resultList = NIL THEN EXIT; resultList _ resultList.rest; d.out.PutF[" %g\n", IO.rope[nowRope]]; ENDLOOP; CreateButtons[d, p.parent.parent]; EXITS badParse => {}; }; PutOwnerProperties: PUBLIC PROC [trans: AlpTransaction.Handle, server: ROPE, directory: ROPE, user: ROPE _ NIL, password: ROPE _ NIL , d: MyData] RETURNS [LIST OF REF ANY] = { resultList: LIST OF REF ANY _ NIL; resultRope: ROPE _ NIL; rootFileHandle: AlpFile.Handle; outcome: AlpTransaction.Outcome; rootUniversalFile: AlpineEnvironment.UniversalFile; properties: LIST OF AlpineEnvironment.OwnerPropertyValuePair; rootNewProperties: LIST OF AlpineEnvironment.PropertyValuePair _ NIL ; fooNewProperties, newProperties: LIST OF AlpineEnvironment.OwnerPropertyValuePair _ NIL ; scratchStream: IO.STREAM _ NIL; failureName: ROPE _ "" ; { ENABLE UNWIND => IF trans # NIL THEN outcome _ AlpTransaction.Finish[trans, abort]; IF trans = NIL THEN GOTO notAlpineFile; IF d.assertWheel THEN trans.AssertAlpineWheel[TRUE]; { newDefaultKeepRope: ROPE _ ViewerTools.GetContents[viewer: d.oOwnerKeep]; newDefaultKeep: LONG CARDINAL; scratchStream _ IO.RIS[newDefaultKeepRope, scratchStream]; newDefaultKeep _ NARROW[IO.GetCard[scratchStream]]; AlpDirectory.SetDefaultKeep[volume: server, owner: directory, transHandle: trans, defaultKeep: newDefaultKeep]; }; properties _ AlpTransaction.ReadOwnerProperties[handle: trans, volumeGroupID: AlpTransaction.GetNextVolumeGroup[handle: trans, previousGroup: AlpineEnvironment.nullVolumeGroupID, lock: [none, fail]], owner: directory]; UNTIL properties = NIL DO -- because ReadOwnerProperties does not sort them yet ... WITH properties.first SELECT FROM q: AlpineEnvironment.OwnerPropertyValuePair.createAccessList => { createList: AlpineEnvironment.AccessList _ q.createAccessList; newCreateList: AlpineEnvironment.AccessList _ NIL ; newCreateListRope: ROPE _ViewerTools.GetContents[viewer: d.oCreateAccessList]; scratchStream _ IO.RIS[newCreateListRope, scratchStream]; newCreateList _ getAccessList[scratchStream]; newProperties _ CONS[[createAccessList[newCreateList]], newProperties]; scratchStream _ IO.RIS[ViewerTools.GetContents[viewer: d.oRootReadAccess], scratchStream]; rootNewProperties _ CONS[[readAccess[getAccessList[scratchStream]]], rootNewProperties]; scratchStream _ IO.RIS[ViewerTools.GetContents[viewer: d.oRootModifyAccess], scratchStream]; rootNewProperties _ CONS[[modifyAccess[getAccessList[scratchStream]]], rootNewProperties]; }; s: AlpineEnvironment.OwnerPropertyValuePair.modifyAccessList => { modifyList: AlpineEnvironment.AccessList _ s.modifyAccessList; newModifyList: AlpineEnvironment.AccessList _ NIL ; fooNewProperties _ CONS[[modifyAccessList[newModifyList]], newProperties]; }; r: AlpineEnvironment.OwnerPropertyValuePair.rootFile => { rootUniversalFile _ r.rootFile; }; ENDCASE; properties _ properties.rest; ENDLOOP; AlpTransaction.WriteOwnerProperties[handle: trans, volumeGroupID: AlpTransaction.GetNextVolumeGroup[handle: trans, previousGroup: AlpineEnvironment.nullVolumeGroupID, lock: [none, wait]], owner: directory, overCommitQuotasIfNeeded: TRUE, properties: newProperties]; [rootFileHandle]_ AlpFile.Open[transHandle: trans, universalFile: rootUniversalFile, access: readWrite, lock: [write, fail]]; AlpFile.WriteProperties[handle: rootFileHandle, properties: rootNewProperties, lock: [read, fail] ! AlpInstance.LockFailed => GOTO lockError]; outcome _ AlpTransaction.Finish[trans, commit]; RETURN [CONS[NARROW[ "Put of owner properties successful",ROPE] ,NIL]]; EXITS lockError => { outcome _ AlpTransaction.Finish[trans, abort]; RETURN[CONS[ NARROW["lock prevents access to root file",ROPE] ,NIL]]; }; notAlpineFile => { RETURN[CONS[ NARROW["Cannot put owner properties for a non-Alpine server",ROPE] ,NIL]]; }; }; }; PutOwnerPropertiesProc: PUBLIC Buttons.ButtonProc = { resultList: LIST OF REF ANY _ NIL; d: MyData = NARROW[clientData]; p: ViewerClasses.Viewer = NARROW[parent]; server, user, file, password: ROPE; directory: ROPE; parseError: BOOL; errorExplanation: ROPE; callPut: YodelData.PerformProc = { RETURN[PutOwnerProperties[trans, server, directory.Substr[start: 1, len: directory.Size[]-2], user, password, d]] }; typeParseError: PROC [] = { d.out.PutF["\nBad pattern in Destroy Owner because %g\n", IO.rope[errorExplanation]]; }; d.stopFlag _ FALSE; [user, password, server, directory, file, parseError, errorExplanation] _ ParseSArgs[d]; IF parseError THEN { typeParseError[]; GOTO badParse;}; d.out.PutF["\nPut Properties for [%g]%g\n", IO.rope[server], IO.rope[directory]]; resultList _ PerformOp[performProc: callPut, server: server, user: user, password: password]; DO nowRope: ROPE _ NARROW[IF resultList = NIL THEN NIL ELSE resultList.first]; IF resultList = NIL THEN EXIT; resultList _ resultList.rest; d.out.PutF[" %g\n", IO.rope[nowRope]]; ENDLOOP; CreateButtons[d, p.parent.parent]; EXITS badParse => {}; }; END. μYodelPropertiesImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Yodel: File and Owner Property commands Last Edited by: Carl Hauser, April 17, 1986 10:14:47 am PST Bob Hagmann June 11, 1985 11:37:55 am PDT byteLength createTime ViewerTools.SetContents[viewer: d.oCreateTime, contents: IO.PutFR["%g", IO.time[createTime]], paint: FALSE]; highWaterMark modifyAccess owner readAccess stringName newSize _ MAX[newSize,size]; byteLength highWaterMark modifyAccess owner readAccess stringName filler to use all the variants so the compiler won't blow up (this is the cedar version of the "don't delete this line" comment The compiler insists that I leave this code here. Bob Hagmann June 10, 1985 5:09:16 pm PDT reformatted ΚY˜šœ™Icodešœ Οmœ1™<—Jšœ'™'šœ™Jšœ+™+K™)—J˜J˜šΟk ˜ J˜J˜J˜ J˜ J˜J˜ J˜J˜ J˜Jšžœ˜J˜J˜J˜ J˜ —J˜Jšœžœž˜"JšžœIžœ˜pJ˜šžœ ˜J˜J˜—J˜Jšžœžœ ˜J˜Jšžœžœžœ˜J˜š Οbœžœ,žœžœžœ˜kJšžœžœžœ.˜Fšžœ˜šžœžœž˜J˜7J˜0J˜Jšžœžœžœ+˜CJšžœ˜—J˜—J˜—J˜šΟn œžœžœ˜7Jšœžœ žœžœ˜*Jš œžœžœ žœžœ˜(J˜FJ˜ Jš žœžœžœžœžœ˜J˜Jšœžœ˜Jšœ žœžœ%˜8Jšœ žœžœ˜J˜J˜ Jšœ žœ˜Jšœ,žœžœžœ˜Q˜Jš žœžœžœ žœžœ/˜SJšžœ žœžœžœ˜'Jšžœžœžœ˜4˜BJ˜—˜'J˜%Jšœ˜J˜J˜—šœL˜LJšœžœ ˜+—J˜˜Jšœžœ˜ J˜˜(Jšœ žœ žœ ˜'Jšœžœ˜——J˜˜Jšœžœ˜JšœV˜Všœ,˜,Jšœ žœ žœ ˜(Jšœžœ˜——J˜šžœžœž˜J˜BJ˜šž˜šžœž˜Jšœ ™ ˜šœ žœžœ ˜"J˜;—˜.Jšœ žœ žœ˜-Jšœžœ˜——˜Jšœ ™ —˜šœžœžœ ˜,J˜;—šœ.™.Jšœ.™.Jšœ™——˜Jšœ ™ —˜šœ-žœ ˜=J˜A—˜1Jšœ žœ žœ˜0Jšœžœ˜——˜Jšœ ™ —˜šœ-žœ ˜=J˜?—J˜1˜0J˜Jšœžœ˜——˜Jšœ™—˜ šœ%žœ ˜5J˜1—˜)Jšœ žœ žœ˜)Jšœžœ˜——˜Jšœ ™ —˜šœ+žœ ˜;J˜;—˜1J˜.J˜Jšœžœ˜——˜Jšœ ™ —˜šœ žœžœ ˜#J˜;—˜.Jšœ žœ žœ˜.Jšœžœ˜——J˜˜ šœ)žœ ˜9J˜5—˜+Jšœ žœ žœ˜*Jšœžœ˜——J˜Jšžœ˜—Jšžœ˜——Jšžœ˜J˜J˜/Jš žœžœžœžœžœ˜>—˜šž˜˜J˜.JšœDžœ˜KJšœGžœ˜NJšœFžœ˜MJšœ?žœ˜FJšœDžœ˜KJšœDžœ˜Kšžœžœ˜ Jšžœ žœ˜+Jšœžœ˜—J˜—˜Jšžœžœ˜ Jšžœ$žœ˜/Jšœžœ˜J˜——J˜ —J˜—J˜J˜J˜šŸ œžœ˜*Jš œ žœžœžœžœžœ˜"Jšœ žœ ˜Jšœžœ ˜)Jšœžœ˜#Jšœžœ˜Jšœ žœ˜Jšœžœ˜Jšœ ž˜ J˜šŸ œ˜&Jšžœ_˜eJ˜—šŸœžœ˜Jšœ1žœ˜LJ˜—J˜Jšœ žœ˜JšœX˜XJšžœ žœžœ ˜7J˜YJšœ(˜(Jšžœ žœ)˜<˜%Jšžœžœžœ˜=—˜0J˜0—šž˜Jšœ žœžœžœžœžœžœžœ˜KJšžœžœžœžœ˜J˜Jšœžœ˜'Jšžœ˜—J˜"šž˜Jšœ˜—Jšœ˜—J˜J˜š Ÿ œžœ žœžœžœ*žœ˜ašžœžœžœ˜Jšœžœžœžœ˜0Jšœžœžœ˜(šžœ žœžœž˜0Jšœ žœžœ,˜A—J˜—Jšžœ˜šž˜Jšœ žœ˜—J˜—J˜J˜š  œžœžœ˜7Jšœžœ žœžœ˜*Jš œžœžœ žœžœ˜(J˜FJ˜ Jš žœžœžœžœžœ˜J˜Jšœžœ˜Jšœžœžœ'žœ˜BJšœ žœžœ%˜8Jšœ žœžœ˜J˜J˜ Jšœžœžœžœ˜Jšœ žœ˜Jšœ,žœžœžœ˜QJšœ.žœžœžœ˜S˜Jš žœžœžœ žœžœ/˜SJšžœ žœžœžœ˜'Jšžœžœžœ˜4˜BJ˜—˜'J˜J˜&Jšœ˜J˜—šœL˜LJšœžœ ˜,—˜Jšœ žœ˜Jšœ žœ˜ Jšœžœ˜ J˜J˜7Jšœžœžœ˜3Jšœ žœžœ˜,Jšœ™J˜J˜—˜Jšœ žœ˜Jšœ ž œ˜Jšœ;˜;Jšœžœžœ˜3Jšœ žœžœ˜-JšœU˜UJ˜—šžœžœž˜J˜BJ˜šœ˜šžœž˜Jšœ ™ ˜Jšœžœ˜Jšœžœ˜šœ žœžœ ˜"J˜;—J˜CJšœžœžœ$˜:Jšœžœ˜*Jšœžœ-˜A—˜Jšœ ™ —˜Jšœžœ˜šœžœ˜J˜2—Jšœžœžœ&˜Jšœ žœ%˜5JšœRžœ˜YJ˜—˜AJ˜>J˜—Jšœ<™Jšœ.žœ˜3Jšœžœ7˜NJšœžœžœ#˜9J˜-Jšœžœ3˜GJšœžœžœD˜ZJšœžœ@˜XJšœžœžœF˜\JšœžœB˜ZJ˜—J˜Ašœ1™1J˜>Jšœ.žœ˜3Jšœžœ3˜JJ˜—˜9J˜ J˜—Jšžœ˜—J˜Jšžœ˜—Jšœθžœ˜‰J˜}Jšœ~žœ ˜Ž—˜J˜/šžœžœžœ˜Jšœ%žœ˜*Jšœžœ˜J˜—šž˜˜J˜.šžœžœ˜ Jšžœ%žœ˜0Jšœžœ˜—J˜—˜šžœžœ˜ Jšžœ7žœ˜BJšœžœ˜—J˜——J˜ —J˜—J˜J˜J˜šŸœžœ˜5Jš œ žœžœžœžœžœ˜"Jšœ žœ ˜Jšœžœ ˜)Jšœžœ˜#Jšœ žœ˜Jšœ žœ˜Jšœžœ˜J˜šŸœ˜"Jšžœk˜qJ˜—šŸœžœ˜Jšœ:žœ˜UJ˜—J˜Jšœ žœ˜J˜JšœX˜XJšžœ žœžœ ˜7Jšœ,žœžœ˜QJ˜]šž˜Jšœ žœžœžœžœžœžœžœ˜KJšžœžœžœžœ˜J˜Jšœžœ˜'—Jšžœ˜J˜"šž˜Jšœ˜—Jšœ˜—J˜Jšžœ˜J˜J˜J˜J˜™(K™ ——…—_{Y