[Oberon] Removing unnecessary and embedded RETURNs.

joerg.straube at iaeth.ch joerg.straube at iaeth.ch
Mon Nov 13 06:37:10 CET 2023


Peter

You said “ReadText is external to this byte padding.” Is it?

RFC 1939 states:

   Responses to certain commands are multi-line.  In these cases, which

   are clearly indicated below, after sending the first line of the

   response and a CRLF, any additional lines are sent, each terminated

   by a CRLF pair.  When all lines of the response have been sent, a

   final line is sent, consisting of a termination octet (decimal code

   046, ".") and a CRLF pair.  If any line of the multi-line response

   begins with the termination octet, the line is "byte-stuffed" by

   pre-pending the termination octet to that line of the response.

   Hence a multi-line response is terminated with the five octets

   "CRLF.CRLF".  When examining a multi-line response, the client checks

   to see if the line begins with the termination octet.  If so and if

   octets other than CRLF follow, the first octet of the line (the

   termination octet) is stripped away.  If so and if CRLF immediately

   follows the termination character, then the response from the POP

   server is ended and the line containing ".CRLF" is not considered

   part of the multi-line response.

As the last line with only “.CRLF” is not considered part of the text, you should delay Files.Write(R, ch); in state 3, 4, 5 until you know whether it’s the termination case or byte-stuffed case.
BTW: the original code does not copy the starting “.” of a line to the file, but copies over the final CRLF. In most cases, this additional CRLF at the end does not harm but is - strictly speaking - not correct.

br
Jörg

Von: joerg.straube at iaeth.ch <joerg.straube at iaeth.ch>
Datum: Montag, 13. November 2023 um 06:08
An: ETH Oberon and related systems <oberon at lists.inf.ethz.ch>
Betreff: AW: [Oberon] Removing unnecessary and embedded RETURNs.
Peter

The idea with the state machine is good.
One remark:
I don’t understand you remark “ReadText is external to this byte padding”
In my point of view in the ELSE part of state 3 you would have to strip the stuffed period.
In other words: you would have to reposition and copy the Files.Write(R, ch); to almost all your cases

br
Jörg

Von: Oberon <oberon-bounces at lists.inf.ethz.ch> im Auftrag von peter at easthope.ca <peter at easthope.ca>
Datum: Sonntag, 12. November 2023 um 15:58
An: oberon at lists.inf.ethz.ch <oberon at lists.inf.ethz.ch>
Betreff: Re: [Oberon] Removing unnecessary and embedded RETURNs.
This is my alternative Mail.ReadText with no RETURN.  ReportError was
helpful in debugging; probably can be deleted now.

Apology for the verbose comments.  Added to help a non-expert
understand the non-obvious activity.  =8~)

I wonder whether this use of CASE is good practise.  Observations?

Thanks,                   ... P.L.

        PROCEDURE ReportError(c: CHAR);
        BEGIN
                Texts.WriteString(W, "Mail.ReadText(): LF absent at CASE "); Texts.Write(W, c);
                Texts.Write(W, "."); Texts.WriteLn(W);
                Texts.Append(Oberon.Log, W.buf); HALT(6)
        END ReportError;

        (* According to Post Office Protocol, the end of a message body is
                marked by character sequence CR LF "." CR LF.
                A message line can begin with a period.  To distinguish from end-of-message,
                the message sender prepends an additional period which is removed before the
                message is displayed to the recipient.  ReadText is external to this byte padding.
                https://en.wikipedia.org/wiki/Post_Office_Protocol
                https://tools.ietf.org/html/rfc1939#section-3 *)
        PROCEDURE ReadText(S: NetTools.Session; VAR R: Files.Rider);
                VAR
                        buffer: ARRAY BufLen OF CHAR;
                        len, readLen, i: SIGNED32;
                        ch: CHAR;
                        progress: CHAR; (*
                                "0"= continuing
                                "1"= CR
                                "2"= CR LF
                                "3"= CR LF "."
                                "4"= CR LF "." CR
                                "5"= CR LF "." CR LF = end-of-message; or no more characters *)
        BEGIN
                readLen := 0;
                i := readLen;
                progress := "0";
                WHILE progress < "5" DO (* Write byte to the MailMessages file. *)
                        IF i = readLen THEN (* More characters required. *)
                                len := NetSystem.Available(S.C);
                                IF (len = 0) & (NetSystem.State(S.C) # NetSystem.inout) THEN
                                        progress := "5"
                                ELSE
                                        IF len > (BufLen-2) THEN readLen := BufLen-2 ELSE readLen := len END;
                                        NetSystem.ReadBytes(S.C, 0, readLen, buffer);
                                        DEC(len, readLen);
                                        i := 0
                                END
                        ELSE (* i < readLen. character available *)
                                ch := buffer[i];
                                CASE progress OF
                                        "0": IF ch = Strings.CR THEN progress := "1" END |
                                        "1": IF ch = Strings.LF THEN progress := "2" ELSE ReportError(progress) END |
                                        "2": IF ch = Strings.CR THEN progress := "1"
                                                ELSIF ch = "." THEN progress := "3" ELSE progress := "0" END |
                                        "3": IF ch = Strings.CR THEN progress := "4" ELSE progress := "0" END |
                                        "4": IF ch = Strings.LF THEN progress := "5" ELSE ReportError(progress) END
                                END;
                                Files.Write(R, ch);
                                INC(i)
                        END
                END
        END ReadText;

-
VoIP:   +1 604 670 0140
work: https://en.wikibooks.org/wiki/User:PeterEasthope

--
Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
https://lists.inf.ethz.ch/mailman/listinfo/oberon
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.inf.ethz.ch/pipermail/oberon/attachments/20231113/bd2bac73/attachment.html>


More information about the Oberon mailing list