-- file: STPOps.mesa  Edited by:
-- Smokey on: 12-Mar-81 12:11:24
-- Evans on: Feb 6, 1980 3:40 PM
-- Karlton on: September 15, 1980  6:01 PM

DIRECTORY
  PupStream USING [CloseReason],
  Stream USING [
    Byte, DeleteProcedure, GetProcedure, Handle, Object, PutProcedure, SubSequenceType, Word],
  STP USING [
    Access, CompletionProcType, ConfirmProcType, ErrorCode, FileInfo, FileType],
  Time USING [Packed];
  
STPOps: DEFINITIONS =
  BEGIN OPEN STP;
  
-- Constants

  maxStringLength: CARDINAL = 100;
  myPassword: CARDINAL = 111111B;
  
-- Types

  Handle: TYPE = POINTER TO Object;
  Object: TYPE = RECORD[
    byteStream: Stream.Handle ← NIL,
    userState: ARRAY UserProperties OF STRING ← ALL[NIL],
    gotMark: BOOLEAN ← FALSE,
    mark: Stream.SubSequenceType ← NULL,
    remoteString: STRING ← NIL,
    host: STRING ← NIL,
    serverType: ServerType ← unknown,
    plist: PList ← NIL,
    info: FileInfo ← NIL,
    remoteStream: RemoteStream ← NIL];
    
  RemoteStream: TYPE = POINTER TO RemoteObject;
  RemoteObject: TYPE = RECORD[
    stream: Stream.Object,
    state: RemoteStreamState,
    access: STP.Access,
    stp: Handle,
    password: CARDINAL ← myPassword];
    
  FilenameType: TYPE = {alto, tenex};
  Operation: TYPE = {delete, directory, retrieve, store};
  ServerType: TYPE = {ifs, tenex, unknown};
  PListArray: TYPE = ARRAY ValidProperties OF STRING;
  PList: TYPE = POINTER TO PListArray;
  RemoteStreamState: TYPE = {initial, confirm, data, complete, end};
  
  ValidProperties: TYPE =
    {userName, userPassword, connectName, connectPassword, directory, nameBody,
    version, createDate, readDate, writeDate, byteSize, type, size, author,
    eolConversion, account, userAccount, device, serverName};
    
  FileProperties: TYPE = ValidProperties[directory..author];
  UserProperties: TYPE = ValidProperties[userName..directory];
  
-- Procedures for doing FTP protocol operations  

  DoFiles: PROCEDURE [
    stp: Handle,
    file: STRING,
    confirm: STP.ConfirmProcType,
    complete: STP.CompletionProcType,
    op: Operation];
  GetCommand: PROCEDURE [stp: Handle, ps: POINTER TO STRING]
    RETURNS[mark: Stream.SubSequenceType, code: CHARACTER];
  GetFile: PROCEDURE [stp: Handle, stream: Stream.Handle, file: STRING]
    RETURNS [BOOLEAN];
  GetHereIsAndPList: PROCEDURE [stp: Handle, gobbleEOC: BOOLEAN ← TRUE];
  GetPList: PROCEDURE [stp: Handle, gobbleEOC: BOOLEAN ← TRUE];
  PutCommand: PROCEDURE [stp: Handle, mark: Stream.SubSequenceType,
    code: CHARACTER, string: STRING, sendEOC: BOOLEAN ← TRUE];
  PutFile: PROCEDURE [stp: Handle, stream: Stream.Handle, file: STRING, sendEOC: BOOLEAN ← TRUE];
  PutPList: PROCEDURE [stp: Handle, mark: Stream.SubSequenceType, sendEOC: BOOLEAN ← TRUE];
  
-- Utility routines

  CollectString: PROCEDURE [stp: Handle, ps: POINTER TO STRING];
  CollectCode: PROCEDURE [stp: Handle] RETURNS[code: CHARACTER];
  CheckConnection: PROCEDURE [stp: Handle];
  ErrorIfNextNotEOC: PROCEDURE [stp: Handle];
  ErrorIfNextNotYes: PROCEDURE [stp: Handle];
  FindFileType: PROCEDURE [stream: Stream.Handle] RETURNS[fileType: FileType];
  GetServerType: PROCEDURE [server: STRING] RETURNS [serverType: ServerType];
  LookAtMark: PROCEDURE [stp: Handle] RETURNS [Stream.SubSequenceType];
  MakeRemoteName: PROCEDURE [plist: PList, type: FilenameType]
    RETURNS[name: STRING];
  MyGetChar: PROCEDURE [stp: Handle] RETURNS [char: CHARACTER];
  MyGetMark: PROCEDURE [stp: Handle] RETURNS [Stream.SubSequenceType];
  MyPutString: PROCEDURE [byteStream: Stream.Handle, string: STRING];
  PropertyString: PROCEDURE [prop: ValidProperties]
    RETURNS [string: STRING]; -- Global string
  SelectError: PROCEDURE [
    stp: Handle, s: STRING, mark: Stream.SubSequenceType];
  SetByteSize: PROCEDURE [stp: Handle, fileType: FileType];
  SetCreateTime: PROCEDURE [stp: Handle, creation: Time.Packed];
  SetFileDates: PROCEDURE [stp: Handle, stream: Stream.Handle];
  SetFileType: PROCEDURE [stp: Handle, fileType: FileType];
  SmashClosed: PROCEDURE [stp: Handle];
  TransferTheFile: PROCEDURE [stp: Handle, from, to: Stream.Handle];
  
-- PList Utilities

  DestroyPList: PROCEDURE [plist: PList] RETURNS [PList];
  MakePList: PROCEDURE RETURNS[plist: PList];
  NameToPList: PROCEDURE [plist: PList, name: STRING, type: FilenameType];
  PListToName: PROCEDURE [plist: PList, type: FilenameType]
    RETURNS[name: STRING];
  PutPListItem: PROCEDURE [byteStream: Stream.Handle,
    property: ValidProperties, value: STRING];
  ResetPList: PROCEDURE [plist: PList];
  SetPListItem: PROCEDURE [plist: PList, property, value: STRING];
  UserStateToPList: PROCEDURE [stp: Handle];
  
-- Remote Stream routines

  FillInStreamObject: PROCEDURE[stream: Stream.Handle];
  DeleteRemoteStream: Stream.DeleteProcedure;
  GetBlock: Stream.GetProcedure;
  GetByte: PROCEDURE [sH: Stream.Handle] RETURNS[byte: Stream.Byte];
  GetError: Stream.GetProcedure;
  GetWord: PROCEDURE [sH: Stream.Handle] RETURNS[word: Stream.Word];
  PutBlock: Stream.PutProcedure;
  PutByte: PROCEDURE [sH: Stream.Handle, byte: Stream.Byte];
  PutError: Stream.PutProcedure;
  PutWord: PROCEDURE [sH: Stream.Handle, word: Stream.Word];
  
-- Internal ERRORs and SIGNALs

  BadProperty: ERROR;
  MarkEncountered: ERROR;
  ErrorCodeToSTPErrorCode: PROCEDURE [errorCode: STP.ErrorCode, code: CHARACTER]
    RETURNS[STP.ErrorCode];
  GenerateErrorString: PROCEDURE [
    errorCode: STP.ErrorCode, string: STRING, code: CHARACTER ← 0C];
  GenerateStreamClosingError: PROCEDURE [why: PupStream.CloseReason];
  GenerateProtocolError: PROCEDURE [
    type: ProtocolError, mark: Stream.SubSequenceType, code: CHARACTER ← 0C];
    
  ProtocolError: TYPE = {badVersion, badMark, badPList, eocExpected, noCode};
  
-- Registered STP Mark Byte Commands

  markRetrieve: Stream.SubSequenceType = 1B;
  markStore: Stream.SubSequenceType = 2B;
  markYes: Stream.SubSequenceType = 3B;
  markNo: Stream.SubSequenceType = 4B;
  markHereIsFile: Stream.SubSequenceType = 5B;
  markEOC: Stream.SubSequenceType = 6B;
  markComment: Stream.SubSequenceType = 7B;
  markIAmVersion: Stream.SubSequenceType = 10B;
  markNewStore: Stream.SubSequenceType = 11B;
  markDirectory: Stream.SubSequenceType = 12B;
  markHereIsPList: Stream.SubSequenceType = 13B;
  markYouAreUser: Stream.SubSequenceType = 14B;
  markAbort: Stream.SubSequenceType = 15B;
  markDelete: Stream.SubSequenceType = 16B;
  markRename: Stream.SubSequenceType = 17B;
  
-- Registered Mail Mark Byte Commands

  markStoreMail: Stream.SubSequenceType = 20B;
  markRetrieveMail: Stream.SubSequenceType = 21B;
  markFlushMailBox: Stream.SubSequenceType = 22B;
  markMailBoxException: Stream.SubSequenceType = 23B;
  
  END. -- end of STPOps