|View script||License||Download documentation as: HTML or editable|
|Download script||History||Other scripts by: iho|
3-Aug 7:01 UTC
Script Library: 1238 scripts
Documentation for: simtpop.r
This is from an email I sent to explain the working of the smtp rule, maybe it helps someone to understand what's going on, otherwise feel free to ask me again ... The smtp-rule works by pretending that you can look at the data sent to an smtp server as being one continous string, say like: HELO Mailserver MAIL FROM me@mydomain RCPT TO you@yourdomain DATA Here comes the actual message text, preceded by the header text, and ended by a dot (".") on a line all by itself, like here: . RSET QUIT and after this you are done with it. Having this static file, you could create a parse rule like this: parse client-commands [ "HELO" thru newline (answer) "MAIL" thru newline (answer) ... ] Of course, in reality, you won't get a continous file, because the client waits for answers from the server, before it sends the new data, and a reas from the port is not guaranteed to get the whole data sent by the client. That's what I'm dealing with in the rule ... ; a sub-rule that will get the next chunk of data from the connection to ; the client, as long as the connection is open, otherwise it sets the ; word 'get-or-end to point to a rule that just goes to the end of the ; string get-data-rule: copy [ (either not none? conn [ append line copy conn ][ get-or-end: copy end-rule ]) ] ; the rule to advance to the end of the string end-rule: [thru end] smtp-rule: [ ( ; set get-or-end to the rule to get new data from the port get-or-end: copy get-data-rule ; we don't yet expect any "data" (actual message text) data-started: false ) ; the following block will be run through multiple times, at ; least once for every command the client issues in a normal ; communication some [ ; save away your current position here: ; this block contains the rules for the several elements of the ; client server communication ; each possible command is checked, along with the data it should contain, ; e.g. the "HELO" command ends with a newline ; if the whole command has been parsed, answer appropriately, otherwise ; check the next command. ; (continued at -2-) [ "HELO" thru newline (answer "250 SiMTPop") | "MAIL" thru newline (answer "250 Ok MAIL FROM") | "RCPT" [thru "<" | thru ": " ] copy name to "@" thru newline (answer "250 Ok RCPT TO") | ; -3- ; the "DATA" rule needs some additional tweaking, because after the ; client told us that it wants to send us the data, it waits for the ; server to be ready to receive, but as the data may potentially be ; very large, this rule may be tried multiple times, so we must ; assure, that the server response is only send once per transaction. ; please read on at -4- "DATA" thru newline (if not data-started [answer "354 start mail input"] data-started: true) copy mail thru "^/.^/" (save-mail name mail data-started: false answer "250 OK Mail recieved") | "RSET" thru newline (answer "250 OK RSET" data-started: false) | ; -4- ; we received the QUIT command, the client has completed its transaction, ; so we set get-or-end to the rule that will end this parse run, after ; we told our "good bye" to the client, of course ; finish this at -5- "QUIT" thru newline (answer "221 Good Bye" close conn get-or-end: copy end-rule) | ; -2- ; this rule steps in, if no command has been recogniced, first (which is ; specifically true at the begin of the parse process, because no data ; has yet been read). The parse ; "pointer" is reset to the position where we started to read, then the ; get-or-end rule is used, which right now contains a rule to read the ; next chunk of data from the client, because if we weren't able to ; recognize a valid command, then the last chunk we received did not ; contain all the data (Apart from possible errors which are not really ; checked). ; If the client closed the connection, it will change get-or-end to point ; to the rule to end the current parse/transaction. ; please read on at -3- :here get-or-end ; -5- ; OK, so the 'get-or-end word above now pointed to the 'end-rule, so we're ; done ] ] ] I hope this was somewhat understable ...