@TITLE SUP03(1,10)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
MAIL DELIVERY
@BOX 4.0
PRODEDURES IN MODULE
1 DELIVER
2 NEW.TRAP
3 TIME.OUT.TRAP
@BOX 6.0
END
@BOX 1.1
#SUP03/1
MODULE RECEIVER (DELIVER);
@BOX 3.1
*GLOBAL 3;
INTEGER I, REC.CH, END.OF.NAME,
        NO.OF.CHARS, IN.CHANNEL, REPLY.CHANNEL, OP.FILE;
LOGICAL8 TRY.AGAIN.FLAG;
LOGICAL8 [14] MESS;
LABEL RETURN.POINT, TIME.OUT.LABEL, EXIT.LABEL;
@BOX 4.1
LSPEC DELIVER ();
PSPEC NEW.TRAP (INTEGER, INTEGER);
PSPEC TIME.OUT.TRAP (INTEGER, INTEGER);
#SUP03.1
#SUP03.2
#SUP03.3
@BOX 6.1
*END;
@END
/P/
@TITLE SUP03/1(1,10)
@COL 1S
@FLOW 1
@BOX 1.0
EXTERNAL ENVIRONMENT
@BOX 1.1
::EXTERNAL ENVIRONMENT
LSPEC IN.CH () / INTEGER;
LSPEC IN.I () / INTEGER;
LSPEC IN.BIN.B () / INTEGER;
LSPEC SELECT.HEADER ();
LSPEC OUT.BIN.B (INTEGER);
LSPEC DEFINE.OUTPUT (INTEGER, ADDR [LOGICAL8], INTEGER, INTEGER, INTEGER, INTEGE
R) / INTEGER;
LSPEC BREAK.INPUT (INTEGER);
LSPEC SELECT.DOC ();
LSPEC RETURN.FROM.TRAP ();
PSPEC TRAP.PROC (INTEGER, INTEGER);
LSPEC SET.TRAP (INTEGER, ADDR TRAP.PROC);
LSPEC END.INPUT (INTEGER, INTEGER);
LSPEC END.OUTPUT (INTEGER, INTEGER);
LSPEC I.ENQ () / INTEGER;
LSPEC OUT.I(INTEGER, INTEGER);
LSPEC OUT.CH (INTEGER);
LSPEC SELECT.INPUT (INTEGER);
LSPEC SELECT.OUTPUT (INTEGER);
LSPEC DEFINE.INPUT (INTEGER, ADDR [LOGICAL8], INTEGER, INTEGER) / INTEGER;
LSPEC DEFINE.IO (INTEGER, ADDR [LOGICAL8], ADDR [LOGICAL8], INTEGER, INTEGER, IN
TEGER, INTEGER) / INTEGER;
LSPEC SET.CH.STATUS (INTEGER, INTEGER, INTEGER, INTEGER);
@END
/P/
@TITLE SUP03.1(1,10)
@COL 1S-2R-3R-4R-5R-6R-8F
@COL 7R
@ROW 5-7
@FLOW 1-2-3-4-5-6-3
@FLOW 7-6
@BOX 1.0
DELIVER
@BOX 2.0
INITIALISATION
@BOX 3.0
RECEIVE MAIL.
SET UP OUTPUT FOR REPLY TO
SENDING PROCESS.
EXTRACT RECIPIENTS USER ID FROM
MESSAGE.
@BOX 4.0
SET UP I/O TO "POST.BOX"
@BOX 5.0
UPDATE NUMBER OF MESSAGES AND ENTER
IT INTO NEW COPY.
COPY FILE TO NEW COPY.
COPY NEW MESSAGE TO THE END
OF THE NEW COPY.
ENTER "Y" INTO THE REPLY
@BOX 6.0
SEND REPLY.
DISPOSE OF REDUNDANT INPUT AND OUTPUT STREAMS
@BOX 7.0
ENTER "N" INTO REPLY
@BOX 8.0
END
@BOX 1.1
PROC DELIVER;
LOGICAL8 NUMBER;
DATAVEC POST.BOX (LOGICAL8)
   "POST.BOX/"
END
@BOX 2.1
-> L4;
L1: -> EX.LABEL;
L2: -> RETURN.PNT;
L3: -> TIME.OUT.LABEL;
L4:
L1 => EXIT.LABEL;
L2 => RETURN.POINT;
L3 => TIME.OUT.LABEL;
SET.TRAP (3, ^NEW.TRAP);
DEFINE.INPUT (3, %"*", %280, 0);
SET.CH.STATUS (3, 1, 0, 0);
FOR I < 9 DO
   POST.BOX [I] => MESS [I];
OD
@BOX 3.1
TIME.OUT.LABEL:
SET.TRAP (6, ^TIME.OUT.TRAP);
SET.TRAP (5, ^TIME.OUT.TRAP);
SELECT.INPUT (3);
"N" => TRY.AGAIN.FLAG;
BREAK.INPUT (3);
DEFINE.OUTPUT (-1, %"REP3*", %100, 0, 0, 0) => REPLY.CHANNEL;
SELECT.OUTPUT (REPLY.CHANNEL);
DATAVEC PREAMBLE (LOGICAL8)
   6 1 0 0 0 0
END
FOR I < 6 DO
   OUT.BIN.B (PREAMBLE [I]);
OD
SELECT.HEADER ();
8 => END.OF.NAME;
WHILE I.ENQ () & 4 = 0 DO
   1 +> END.OF.NAME;
   IN.CH () => MESS [END.OF.NAME];
OD
SET.TRAP (6, ^NEW.TRAP);
SET.TRAP (5, ^NEW.TRAP);
@BOX 4.1
RETURN.PNT:
-1 => IN.CHANNEL => OP.FILE;
DEFINE.IO (-1, %"SCR*", PART (^MESS, 0, END.OF.NAME), 0, 64, 0, 0) => OP.FILE;
DEFINE.INPUT (-1, PART (^MESS, 0, END.OF.NAME), %18, 0) => IN.CHANNEL;
@BOX 5.1
SELECT.INPUT (IN.CHANNEL);
SELECT.OUTPUT (OP.FILE);
OUT.I (IN.I () + 1, 0);
WHILE I.ENQ () & 8 = 0 DO
   OUT.BIN.B (IN.BIN.B());
OD
NEWLINES (1);
SELECT.INPUT (3);
SELECT.DOC ();
WHILE I.ENQ () & 4 = 0 DO
   OUT.BIN.B (IN.BIN.B());
OD
SELECT.OUTPUT (REPLY.CHANNEL);
OUT.CH ("Y");
@BOX 6.1
END.INPUT (IN.CHANNEL, 0);
END.OUTPUT (OP.FILE, 0);
END.OUTPUT (REPLY.CHANNEL, 0);
@BOX 7.1
EX.LABEL:
SELECT.OUTPUT (REPLY.CHANNEL);
OUT.CH ("N");
@BOX 8.1
END
@END
/P/
@TITLE SUP03.2(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
NEW TRAP
@BOX 2.0
IF IT IS A CLASS 5 TRAP
DISPOSE OF ANY CHANNELS JUST SET UP
CREATE RECIPIENTS "POST.BOX".
RETURN TO TRY AGAIN TO DELIVER.
IF IT IS A CLASS 6 TRAP
RETURN TO SEND A FAILURE REPLY
OTHERWISE IT MUST BE CLASS 3 SO CONTINUE
FROM WHERE THE TRAP OCCURED.
@BOX 3.0
END
@BOX 1.1
PROC NEW.TRAP (CLASS, REASON);
INTEGER I, CHNNL;
@BOX 2.1
IF CLASS = 5 THEN
   IF TRY.AGAIN.FLAG /= "Y" THEN
      IF IN.CHANNEL > 0 THEN
         END.INPUT (IN.CHANNEL, 0);
         END.OUTPUT (IN.CHANNEL, 0);
      FI
      IF OP.FILE > 0 THEN
         END.INPUT (OP.FILE, 0);
      FI
      "Y" => TRY.AGAIN.FLAG;
      DEFINE.OUTPUT (-1, PART (^MESS, 0, END.OF.NAME ), 0, 0, 0, 0) => CHNNL;
      SELECT.OUTPUT (CHNNL);
      OUT.I (0, 0);
      OUT.CH ("$L");
      OUT.I (0, 0);
      FOR I < 4 DO
         OUT.CH ("$L");
      OD
      END.OUTPUT (CHNNL, 0);
      -> RETURN.POINT;
   ELSE
      -> EXIT.LABEL;
   FI
FI
IF CLASS = 6 THEN
   -> EXIT.LABEL;
FI
RETURN.FROM.TRAP ();
@BOX 3.1
END
@END
/P/
@TITLE SUP03.3(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TIME OUT TRAP
@BOX 2.0
TIDY UP AND RETURN TO WAIT AGAIN
@BOX 3.0
END
@BOX 1.1
PROC TIME.OUT.TRAP (CLASS, REASON);
@BOX 2.1
END.OUTPUT (REPLY.CHANNEL, 0);
-> TIME.OUT.LABEL;
@BOX 3.1
END
@END


