-- FTPProtFiles.mesa, Edit: HGM July 28, 1980 8:56 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY FTPDefs, FTPPrivateDefs, String USING [AppendDecimal, AppendLongNumber, AppendString, EquivalentString, StringToDecimal, StringToLongNumber]; FTPProtFiles: PROGRAM IMPORTS String, FTPPrivateDefs EXPORTS FTPPrivateDefs SHARES FTPDefs = BEGIN OPEN FTPDefs, FTPPrivateDefs; -- **********************! Constants !*********************** ftpsystem: POINTER TO FTPSystem = LocateFtpSystemObject[]; -- **********************! Filename Primitives !*********************** WriteFilename: PUBLIC PROCEDURE [file: STRING, propertyList: PropertyList, filePrimitives: FilePrimitives, fileSystem: FileSystem, userPropertyList: PropertyList] = BEGIN OPEN filePrimitives; -- Note: Local filename iff filePrimitives present; -- accompanies remote filename with credentials. -- local constants device: STRING = [maxStringLength]; directory: STRING = [maxStringLength]; name: STRING = [maxStringLength]; version: STRING = [maxStringLength]; -- local variables virtualFilenameObject: VirtualFilenameObject ← [ device: device, directory: directory, name: name, version: version]; -- local filename: construct and output virtual filename IF filePrimitives # NIL THEN BEGIN DecomposeFilename[fileSystem, file, @virtualFilenameObject]; WriteVirtualFilename[@virtualFilenameObject, propertyList, FALSE]; END -- remote filename: output virtual filename and credentials ELSE CopyPropertyList[userPropertyList, propertyList]; -- output absolute filename WriteProperty[propertyList, serverFilename, file]; END; ReadFilename: PUBLIC PROCEDURE [file: STRING, propertyList: PropertyList, filePrimitives: FilePrimitives, fileSystem: FileSystem] = BEGIN OPEN filePrimitives; -- Note: Local filename iff filePrimitives present; -- examines credentials accompanying local filename; takes name body property -- as remote filename in absence of server filename property. -- local constants device: STRING = [maxStringLength]; directory: STRING = [maxStringLength]; name: STRING = [maxStringLength]; version: STRING = [maxStringLength]; -- local variables virtualFilenameObject: VirtualFilenameObject ← [ device: device, directory: directory, name: name, version: version]; property: Property; -- initialize filename to empty file.length ← 0; -- local filename: use combination of absolute and virtual filenames IF filePrimitives # NIL THEN BEGIN -- examine credentials ExamineCredentials[propertyList, filePrimitives, fileSystem]; -- initialize to absolute filename IF propertyList[serverFilename] # NIL THEN String.AppendString[file, propertyList[serverFilename]]; -- use virtual filename to default missing filename components ReadVirtualFilename[@virtualFilenameObject, propertyList]; ComposeFilename[fileSystem, file, @virtualFilenameObject]; END -- remote filename: use absolute filename ELSE BEGIN property ← SELECT FALSE FROM (propertyList[serverFilename] = NIL) => serverFilename, (propertyList[nameBody] = NIL) => nameBody, ENDCASE => version; IF property # version THEN String.AppendString[file, propertyList[property]]; END; END; WriteVirtualFilename: PUBLIC PROCEDURE [virtualFilename: VirtualFilename, propertyList: PropertyList, skipNullComponents: BOOLEAN] = BEGIN OPEN virtualFilename; -- Note: Virtual filename components are never NIL. -- WriteComponent procedure WriteComponent: PROCEDURE [property: Property, value: STRING] = BEGIN IF ~(skipNullComponents AND value.length = 0) THEN WriteProperty[propertyList, property, value]; END; -- store virtual filename components in property list WriteComponent[device, device]; WriteComponent[directory, directory]; WriteComponent[nameBody, name]; WriteComponent[version, version]; END; ReadVirtualFilename: PUBLIC PROCEDURE [virtualFilename: VirtualFilename, propertyList: PropertyList] = BEGIN OPEN virtualFilename; -- Note: Virtual filename components are never NIL. -- ReadComponent procedure ReadComponent: PROCEDURE [property: Property, value: STRING] = BEGIN IF propertyList[property] # NIL THEN String.AppendString[value, propertyList[property]]; END; -- initialize components to empty device.length ← directory.length ← name.length ← version.length ← 0; -- retrieve virtual filename components from property list ReadComponent[device, device]; ReadComponent[directory, directory]; ReadComponent[nameBody, name]; ReadComponent[version, version]; END; -- **********************! File Attribute Primitives !*********************** ExamineCredentials: PUBLIC PROCEDURE [propertyList: PropertyList, filePrimitives: FilePrimitives, fileSystem: FileSystem] = BEGIN OPEN filePrimitives; -- Note: Destroys the credentials after examining them. -- examine primary credentials IF propertyList[userName] # NIL THEN BEGIN -- inspect credentials InspectCredentials[fileSystem, primary, propertyList[userName], propertyList[userPassword]]; -- reset them to empty to avoid their being echoed WriteProperty[propertyList, userName, NIL]; WriteProperty[propertyList, userPassword, NIL]; END; -- examine secondary credentials IF propertyList[connectName] # NIL THEN BEGIN -- inspect credentials InspectCredentials[fileSystem, secondary, propertyList[connectName], propertyList[connectPassword]]; -- reset them to empty to avoid their being echoed WriteProperty[propertyList, connectName, NIL]; WriteProperty[propertyList, connectPassword, NIL]; END; END; WriteFileInfo: PUBLIC PROCEDURE [propertyList: PropertyList, fileInfo: FileInfo] = BEGIN OPEN fileInfo; -- Note: EOL convention, for text files, is always CR. -- local constants textualByteSize: STRING = [maxStringLength]; textualByteCount: STRING = [maxStringLength]; -- encode file type EncodeFileType[propertyList, fileType]; -- write byte size and byte count IF byteSize # 0 THEN String.AppendDecimal[textualByteSize, byteSize]; WriteProperty[propertyList, byteSize, textualByteSize]; IF byteCount # 0 THEN String.AppendLongNumber[textualByteCount, byteCount, 10]; WriteProperty[propertyList, size, textualByteCount]; -- write dates and author WriteProperty[propertyList, creationDate, creationDate]; WriteProperty[propertyList, writeDate, writeDate]; WriteProperty[propertyList, readDate, readDate]; WriteProperty[propertyList, author, author]; END; ReadFileInfo: PUBLIC PROCEDURE [propertyList: PropertyList, fileInfo: FileInfo] = BEGIN -- Note: File information object will address property list strings; -- EOL convention, for text files, is always CR. -- local constants textualByteSize: STRING = propertyList[byteSize]; textualByteCount: STRING = propertyList[size]; -- assemble file information fileInfo↑ ← FileInfoObject[ fileType: DecodeFileType[propertyList], byteSize: IF textualByteSize = NIL THEN 0 ELSE String.StringToDecimal[textualByteSize], byteCount: IF textualByteCount = NIL THEN 0 ELSE String.StringToLongNumber[textualByteCount, 10], creationDate: propertyList[creationDate], writeDate: propertyList[writeDate], readDate: propertyList[readDate], author: propertyList[author]]; END; EncodeFileType: PUBLIC PROCEDURE [propertyList: PropertyList, fileType: FileType] = BEGIN -- local constants textualFileType: STRING = SELECT fileType FROM text => "Text"L, binary => "Binary"L, ENDCASE => NIL; -- unknown -- write file type WriteProperty[propertyList, type, textualFileType]; END; DecodeFileType: PUBLIC PROCEDURE [propertyList: PropertyList] RETURNS [fileType: FileType] = BEGIN -- local constants textualFileType: STRING = propertyList[type]; -- read file type SELECT TRUE FROM (textualFileType = NIL) => fileType ← unknown; String.EquivalentString[textualFileType, "Text"L] => fileType ← text; String.EquivalentString[textualFileType, "Binary"L] => fileType ← binary; ENDCASE => Abort[illegalFileType]; END; END. -- of FTPProtFiles