YodelPropertiesImpl.mesa
Copyright © 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
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: ROPENIL] = {
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: ROPENIL, password: ROPENIL ,
displayProperties: AlpineFile.PropertySet ← AlpineFile.allProperties,
d: MyData]
RETURNS [LIST OF REF ANY] = {
fullFileName: ROPE;
properties: LIST OF AlpineEnvironment.PropertyValuePair;
resultRope: ROPENIL;
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 => {
byteLength: INTNARROW[property,
AlpineEnvironment.PropertyValuePair.byteLength].byteLength;
ViewerTools.SetContents[viewer: d.oByteLength,
contents: IO.PutFR["%g", IO.int[byteLength]],
paint: FALSE];
};
createTime
createTime => {
createTime: BasicTime.GMTNARROW[property,
AlpineEnvironment.PropertyValuePair.createTime].createTime;
ViewerTools.SetContents[viewer: d.oCreateTime,
contents: IO.PutFR["%g", IO.time[createTime]],
paint: FALSE];
};
highWaterMark
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 => {
modifyAccess: AlpineEnvironment.AccessList ← NARROW[property,
AlpineEnvironment.PropertyValuePair.modifyAccess].modifyAccess;
resultRope ← accessListToCommaROPE[modifyAccess];
ViewerTools.SetContents[viewer: d.oModifyAccess,
contents: resultRope,
paint: FALSE];
};
owner
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 => {
readAccess: AlpineEnvironment.AccessList ← NARROW[property,
AlpineEnvironment.PropertyValuePair.readAccess].readAccess;
resultRope ← accessListToCommaROPE[readAccess] ;
ViewerTools.SetContents[viewer: d.oReadAccess,
contents: resultRope,
paint: FALSE];
};
stringName
stringName => {
stringName: ROPENARROW[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 ANYNIL;
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: ROPENARROW[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: ROPEIO.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: ROPENIL, password: ROPENIL ,
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: ROPENIL;
fileHandle: AlpFile.Handle;
outcome: AlpTransaction.Outcome;
scratchStream: IO.STREAMNIL;
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]] ;
newSize ← MAX[newSize,size];
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
byteLength => {
newByteLengthRope: ROPE;
newByteLength: INT ;
byteLength: INTNARROW[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
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
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
owner => {
newOwnerRope: ROPE;
newOwner: ROPE;
newOwnerRope ← ViewerTools.GetContents[viewer: d.oOwner];
newOwner ← NARROW[newOwnerRope];
newProperties ← CONS[[owner[newOwner]], newProperties];
};
readAccess
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
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 ANYNIL;
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: ROPENARROW[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: ROPENIL, password: ROPENIL ,
d: MyData]
RETURNS [LIST OF REF ANY] = {
resultList: LIST OF REF ANYNIL;
resultRope: ROPENIL;
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 ANYNIL;
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: ROPENIL, password: ROPENIL , d: MyData] RETURNS [LIST OF REF ANY] = {
resultList: LIST OF REF ANYNIL;
resultRope: ROPENIL;
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;
};
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
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 ANYNIL;
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: ROPENARROW[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: ROPENIL, password: ROPENIL , d: MyData] RETURNS [LIST OF REF ANY] = {
resultList: LIST OF REF ANYNIL;
resultRope: ROPENIL;
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.STREAMNIL;
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 => {
The compiler insists that I leave this code here.
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 ANYNIL;
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: ROPENARROW[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.
Bob Hagmann June 10, 1985 5:09:16 pm PDT
reformatted