-- File: PressNetSender.mesa: Routines for sending a file to a printing server. -- Last February 8, 1982 1:59 PM By: GWilliams -- Can now talk to Platemaker. DIRECTORY EFTPDefs USING [EFTPAbortCode, EFTPFinishSending, EFTPNotSending, EFTPOpenForSending, EFTPSendBlock, EFTPTimeOut, EFTPTroubleSending], PressNetDefs USING [attributesCode, DLP1Attributes, imageCode, PageAttributes, PressNetErr, Printer, StingerAttributes, PrinterAttributes], PupDefs USING [GetPupAddress, PupNameTrouble, PupPackageDestroy, PupPackageMake], PupStream USING [NameLookupErrorCode], PupTypes USING[PupAddress, PupSocketID], Storage USING [CopyString, FreeStringNil]; PressNetSender: PROGRAM IMPORTS EFTPDefs, PupDefs, Storage EXPORTS PressNetDefs = BEGIN OPEN EFTPDefs, PressNetDefs, PupDefs, PupTypes, Storage; --Pack Variables firstScan, lastScan: CARDINAL; pupPtr: POINTER TO PupAddress _ @sendToAddress; sendErrorText: STRING _ NIL; sendToAddress: PupAddress; sendingRetries: CARDINAL _ 1; scanLineLength: CARDINAL; PressSendError: PUBLIC ERROR [err: PressNetErr, s: STRING]= CODE; SendBuf: TYPE = MACHINE DEPENDENT RECORD [code: CARDINAL, pageAttributes: PageAttributes ]; --Procs GetPrinterAttributes: PUBLIC PROCEDURE[printer: Printer] RETURNS [pa: PrinterAttributes]= { SELECT printer FROM Stinger => RETURN[StingerAttributes]; DLP1 => RETURN[DLP1Attributes]; ENDCASE; };--GetPrinterAttributes PrinterReady: PUBLIC PROCEDURE [printer: Printer, retries: CARDINAL _ 1] RETURNS [goAhead: BOOLEAN _ FALSE]= --If returns successfully, you have a connection. --Later may return reason for no connection (i.e., printer down, not listening etc) { pressNetErr: PressNetErr _ noError; deviceString: STRING; stingerString: STRING _ "Stinger"; dLP1String: STRING _ "Platemaker"; SELECT printer FROM Stinger => deviceString _ stingerString; DLP1 => deviceString _ dLP1String; ENDCASE; BEGIN PupPackageMake[]; GetPupAddress[pupPtr, deviceString! PupNameTrouble => {SELECT code FROM noRoute => pressNetErr _ errorNoRoute; noResponse => pressNetErr _ errorNoResponse; errorFromServer => pressNetErr _ errorFromServer; ENDCASE; GOTO exit;}; --do the GOTO to start UNWIND ]; pupPtr.socket _ PupSocketID[1, 25B]; --[0, 20B] is the normal printer socket EFTPOpenForSending[pupPtr^, TRUE! EFTPTroubleSending => {IF s # NIL THEN sendErrorText _ CopyString[s, 0]; SELECT e FROM eftpOK => pressNetErr _ errorEftpOK; eftpExternalReceiverAbort => pressNetErr _ errorEftpExternalReceiverAbort; eftpReceiverBusyAbort => pressNetErr _ errorEftpReceiverBusyAbort; eftpOutOfSyncAbort => pressNetErr _ errorEftpOutOfSyncAbort; eftpRejected => pressNetErr _ errorEftpRejected; ENDCASE; GOTO exit; }; EFTPTimeOut => IF (retries _ retries - 1) > 0 THEN RESUME ELSE {pressNetErr _ errorTimedOut; GOTO exit}; ]; goAhead _ TRUE; EXITS exit => BEGIN ENABLE UNWIND => IF sendErrorText # NIL THEN sendErrorText_FreeStringNil[sendErrorText]; PupPackageDestroy[]; SELECT pressNetErr FROM errorNoRoute => ERROR PressSendError[pressNetErr, "Can't Get there from here"]; errorNoResponse => ERROR PressSendError[pressNetErr, "Lookup Server doesn't respond"]; errorFromServer => ERROR PressSendError[pressNetErr, "Lookup Server error."]; errorEftpOK, errorEftpExternalReceiverAbort, errorEftpReceiverBusyAbort, errorEftpOutOfSyncAbort => ERROR PressSendError[pressNetErr, sendErrorText]; errorEftpRejected, errorTimedOut => NULL; --simply return FALSE ENDCASE; END; --of ENABLE for UNWIND END; };--PrinterReady SetRetries: PUBLIC PROC[n: CARDINAL]= --this sets the retry count for all transfers after the connection is established { sendingRetries _ n}; SendLine: PUBLIC PROC[p: LONG POINTER]= BEGIN SendBuffer[p, scanLineLength, sendingRetries, imageCode];--length in words END; --of SendLine SendPageAttributes: PUBLIC PROCEDURE[attrPt: POINTER TO PageAttributes]= --this routine sends the page attributes to the printer. --If goAhead returns FALSE, there was trouble with the parameters and the connection is closed. { sendBuf: SendBuf; --let PressNetListener figure out all the PageG entries. scanLineLength _ attrPt.bitWc; firstScan _ attrPt.firstScan; lastScan _ attrPt.lastScan; sendBuf.pageAttributes _ attrPt^; --will this copy the whole record? sendBuf.code _ attributesCode; --send the info SendBuffer[@sendBuf, SIZE[SendBuf], sendingRetries, ]; --code is already in block };--SendPageAttributes SendBuffer: PROC[p: LONG POINTER, len, timeout: CARDINAL, code: CARDINAL _ 0]= --This routine calls SendBlock and renames all Errors for user BEGIN pressNetErr: PressNetErr _ noError; BEGIN --every buffer sent to the printer has a 1-word code at the beginning IF code # 0 THEN {EFTPSendBlock[@code, 2! --send the 2-byte code EFTPTroubleSending => {IF s # NIL THEN sendErrorText _ CopyString[s, 0]; SELECT e FROM eftpOK => pressNetErr _ errorEftpOK; eftpExternalReceiverAbort => pressNetErr _ errorEftpExternalReceiverAbort; eftpReceiverBusyAbort => pressNetErr _ errorEftpReceiverBusyAbort; eftpOutOfSyncAbort => pressNetErr _ errorEftpOutOfSyncAbort; eftpRejected => pressNetErr _ errorEftpRejected; ENDCASE; GOTO exit; }; EFTPNotSending => {pressNetErr _ errorNotSending; GOTO exit}; EFTPTimeOut => IF (timeout _ timeout - 1) # 0 THEN RETRY ELSE {pressNetErr _ errorTimedOut; GOTO exit}; ]; }; EFTPSendBlock[p, len*2! EFTPTroubleSending => {IF s # NIL THEN sendErrorText _ CopyString[s, 0]; SELECT e FROM eftpOK => pressNetErr _ errorEftpOK; eftpExternalReceiverAbort => pressNetErr _ errorEftpExternalReceiverAbort; eftpReceiverBusyAbort => pressNetErr _ errorEftpReceiverBusyAbort; eftpOutOfSyncAbort => pressNetErr _ errorEftpOutOfSyncAbort; eftpRejected => pressNetErr _ errorEftpRejected; ENDCASE; GOTO exit; }; EFTPNotSending => {pressNetErr _ errorNotSending; GOTO exit}; EFTPTimeOut => IF (timeout _ timeout - 1) # 0 THEN RETRY ELSE {pressNetErr _ errorTimedOut; GOTO exit}; ]; EXITS exit => BEGIN ENABLE UNWIND => IF sendErrorText # NIL THEN sendErrorText_FreeStringNil[sendErrorText]; PupPackageDestroy[]; SELECT pressNetErr FROM errorNoRoute => ERROR PressSendError[pressNetErr, "Can't Get there from here"L]; errorNoResponse => ERROR PressSendError[pressNetErr, "Lookup Server doesn't respond"L]; errorFromServer => ERROR PressSendError[pressNetErr, "Lookup Server error."L]; errorEftpOK, errorEftpExternalReceiverAbort, errorEftpReceiverBusyAbort, errorEftpOutOfSyncAbort, errorEftpRejected => ERROR PressSendError[pressNetErr, sendErrorText]; errorTimedOut => ERROR PressSendError[pressNetErr, "Timed out while sending data."L]; ENDCASE; END; --of ENABLE for UNWIND END; END; --SendBuffer CloseConnection: PUBLIC PROC[]= --A connection will be kept open until this routine is called. Don't forget to call it! { nRetries: CARDINAL _ 5; EFTPFinishSending[! EFTPNotSending => CONTINUE; EFTPTimeOut => IF (nRetries _ nRetries - 1) # 0 THEN RESUME ELSE GOTO timeout]; PupPackageDestroy[]; EXITS timeout => PupPackageDestroy[]; };--CloseConnection END. -- PressNetSender.mesa -- Last Edited: October 20, 1981 4:13 PM By: GWilliams -- Last Edited: October 27, 1981 5:15 PM By: GWilliams -- added totalBytesRead -- Last Edited: November 17, 1981 3:17 PM By: GWilliams -- Changing the thrust of the program to transmit the image information on a scan-line basis rather -- than by trying to send press.bits as an intact file. This decouples knowledge of press.bits -- from the image. -- Last Edited: December 8, 1981 5:33 PM By: GWilliams -- Started debugging. -- Last Edited: December 10, 1981 11:22 AM By: GWilliams -- in PrinterReady, now just return FALSE if I catch eftpRejected ("no such port"). This is raised -- if EFTP is running on another port at the printer. -- Last Edited: December 15, 1981 11:51 AM By: GWilliams -- Changed CloseConnection to not do an EFTPFinishSending. If the transfer was successful, the receiving end closed the connection already and the finishsending causes the printer to botch the print. -- Last Edited: 23-Dec-81 14:54:33 By: GWilliams -- SendLine now takes a long pointer. -- Last Edited: 4-Jan-82 18:16:42 By: GWilliams -- Call PupPackageDestroy before raising any error from SendBlock. (635)\1002b1B