diff options
author | Jannis Hoffmann <jannis@fehcom.de> | 2024-07-03 15:48:04 +0200 |
---|---|---|
committer | Jannis Hoffmann <jannis@fehcom.de> | 2024-07-03 15:48:04 +0200 |
commit | 89b7b67a13ebb7965cc7f13ad0595e2194a2d34c (patch) | |
tree | 25efd77a90ae87236e6730d8ea3846bbe0fd126f /doc/Old |
add sqmail-4.2.29asqmail-4.2
Diffstat (limited to 'doc/Old')
-rw-r--r-- | doc/Old/PROPOSAL.mav | 124 | ||||
-rw-r--r-- | doc/Old/README.djbdns | 63 | ||||
-rw-r--r-- | doc/Old/README.mav | 96 | ||||
-rw-r--r-- | doc/Old/README.qmq | 73 | ||||
-rw-r--r-- | doc/Old/README.recipients | 256 | ||||
-rw-r--r-- | doc/Old/README.wildmat | 100 |
6 files changed, 712 insertions, 0 deletions
diff --git a/doc/Old/PROPOSAL.mav b/doc/Old/PROPOSAL.mav new file mode 100644 index 0000000..4e10d8a --- /dev/null +++ b/doc/Old/PROPOSAL.mav @@ -0,0 +1,124 @@ +Mail From: Address Verification, MAV-2005 +Copyright 2005 + +Erwin Hoffmann, feh@fehcom.de + + +1. Scope + +SMTP is a protocol with very few commands. Only 'Helo'/'Ehlo', +'Mail From:', 'Rcpt To:', 'Data' and 'Quit' are necessary +to initiate, perform, and terminate a SMTP session. Here, +the 'Helo'/'Ehlo' provides information about the sending MTA, +which in current MTA implementations is not always required, +while the 'Mail From:' and 'Rcpt To:' is used to build the +SMTP envelope. + +Apart from the 'Rcpt To:' information, the recipient MTA can +not verify any other information. Both the 'Helo'/'Ehlo' and the +'Mail From:' is often forged or faked, thus not reliable in +particular in case of Spam emails. + +The proposed 'Mail From:' Address Verification (MAV) implements +a scheme, how the associated information can be verified at the +responsible sending email gateway and perhaps can be promoted to the +recipient MTA. In this scheme, the provided 'Mail From:' information +is authoritive. + + +2. Responsible Email Gateway + +MAV takes place at the responsible email gateway. The responsible +email gateway acts as relaying gateway for those networks and users +solely transmitting (and receiving) SMTP emails through this gateway. + +Though SMTP is a Host-to-Host protocol, SMTP Authentication yields +a User-to-Host mechanism. Thus, the responsible gateway has to take +care about the following senders: + +(1) networks/hosts, identified by there IP or FQDN (available by + DNS lookup), +(2) users/senders, identified by means of SMTP Authentication or other + mechanisms like POP-before-SMTP. + +With MAV, it is possible to check and verify the integrity of the +provided 'Mail From:' envelope address + +(a) domain-based, by means of the provided IP-address/FQDN of the + sending MTA, +(b) user-based, in case SMTP Authentication (or another user-based + method) is in place. + +Typically in the first case, only the domain-part of the 'Mail From:' +SMTP envelope address can be verified (the part right from the '@', +i.e. user@domain), while in the second case the full qualified +address may be subject of the MAV, providing a mapping between the +userid for SMTP Authentication and the chosen 'Mail From:' address. + + +3. Comparision with other verification schemes + +Today, it is common to reject emails in case it fails certain +authorization/verification criteria: + +(1) Testing the IP address of the sending MTA against Realtime Blacklists + (RBL) available on the Internet, +(2) verification of the domain-part of the provided 'Mail From:' address + doing a DNS lookup (reverse Return-Path must exist) or SMTP lookups, +(3) employing the Sender Policy Framework (SPF), thus checking whether + the domain-part of the 'Mail From:' address is authoritive with + respect to the sending MTA, +(4) verifying (locally) the existance of the forseen recipient ('Rcpt To:'), +(5) checking the contents of the email by means of baysean approaches + or by checksums. + +In any case, the receiving MTA is responsible to realize more or less +complex checks to accept or reject emails applying those means. + +Opposite to this, MAV adds a qualification to the responsible email +gateway; comparable with SMTP Authentication. + + +4. MAV enabled responsibe email gateway + +The tasks of a MAV enabled responsibe gateway are the following: + +(1) The gateway is knowledgeable about those emails to be allowed + for unrestricted relaying. Typically this is facilitated due + to the knowledge to the sender's IP/FQDN or by means of SMTP + Authentication, Pop-before-SMTP, or any other. +(2) The gateway has access to a list which maps the sender + qualification information with a list of allowed domains as + part of the 'Mail From:' address or particular 'Mail From:' + addresses. +(3) Emails failing this test will be rejected initially during + the SMTP session. +(4) Emails passing the test are allowed to relay. +(5) The gateway adds the keyword 'ESMTPM' into the receiving + email header. Thus, the next hop email system is able to + verify the authoritive usage of the 'Mail From:' address. + + +5. Dependencies on other email RFCs + +- RFC 2821: Service extensions: None. +- RFC 1893: Enhanced Mail System Status Codes: None. +- RFC 3848: ESMTP and LMTP Transmission Types Registration: Yes. + MAV adds a new keyword 'ESMTPM' which complements the keywords + 'ESMTPA' and 'ESMTPS'; thus in addition the combinations + 'ESMTPAM', 'ESMTPSM', and 'ESMTPSAM' are valid. + + +6. Security considerations + +Information in the email header is easy to forge or manipulate. + + +7. History + +Parts of the MAV approach was first introduced in the SPAMCONTROL +patch for Qmail 1.03, based on ideas initiated by the LDI, Mainz, Germany. + + + + diff --git a/doc/Old/README.djbdns b/doc/Old/README.djbdns new file mode 100644 index 0000000..c87897b --- /dev/null +++ b/doc/Old/README.djbdns @@ -0,0 +1,63 @@ +QMAIL + DJBDNS +============== + +You may want to link qmail's DNS lookups +against DJBDNS and not against libresolv +as provided by Nikola Vladov. + +Here's the provisionell bootstrapping recipe + +1. Step: + +- Install: qmail as ./qmail-1.03 + +- make qmail (after you have raised accounts + dirs) + +- Install: djbdns as ./djbdns-1.05. + *) You may need to fix "error.h" in the above djbdns-dir: + Edit conf-cc: + + cc -O2 -include /usr/include/errno.h + + **) You want to increase the UDP buffer from 513 to 4097 byte: + Edit dns_transmit.c: + + int dns_transmit_get(struct dns_transmit *d,const iopause_fd *x,const struct taia *when) + { + char udpbuf[4097]; /* instead original buffer [513] byte */ + unsigned char ch; + +- Now do 'make setup' in djbdns-1.05. + + +2. Step: + +- Download: http://riemann.fmi.uni-sofia.bg/vladov/ftp/djbdns+qmail.tar.gz + (it is also part of SPAMCONTROL). + +- Untar Nikola's patch in djbdns-1.05 (and read his README.qmail). + +- Adjust the path to the qmail dir: conf-qmail (if necessary). + +- Install Nikola's patch: make -f Makefile.qmail + +- Test the patch: make -f Makefile.qmail check + + +3. Step: + +- Untar SPAMCONTROL in the qmail-1.03 source directory. + +- Edit conf-djbdns and include the path to djbdns-1.05 (if necessary). + +- Run install_spamcontrol.sh and see in the spamcontrol.log if changes applied. + +- (Re)Make qmail: make setup check. + + +4. Step: + +- Enjoy and relax. Now qmail-remote + qmail-smtpd use djbdns libs instead of libresolv. + + +--eh. 2010-04-26 diff --git a/doc/Old/README.mav b/doc/Old/README.mav new file mode 100644 index 0000000..761155f --- /dev/null +++ b/doc/Old/README.mav @@ -0,0 +1,96 @@ +Mail Address Verification (MAV) +=============================== + +Introduction +------------ + +Mail Address Verification (MAV) makes the +'Mail From:' envelope sender address authoritive. +This is facilitated by comparing the received +'Mail From:' address in the SMTP dialoge, with a list +of addresses/domains included in a list matching + +(1) the userid (=> $TCPREMOTEINFO). +(2) the IP (=> $TCPREMOTEIP), +(3) the FQDN (=> $TCPREMOTHOST), + +of the connecting SMTP client to qmail-smtpd. + + +MAV invocation +-------------- + +Use the evironment variable 'LOCALMFCHECK' by +means of the qmail-smtpd start script or by means +of tcpserver's cdb file with the following definitions: + +(1) LOCALMFCHECK="" - unqualified checking against + control/rcpthosts +(2) LOCALMFSCHECK="!" - qualified checking against + control/mailfromrules.cdb +(3) LOCALMFCHECK="example.com" - qualified checking + with fixed name + + +MAV database +------------ + +Include into the file contol/mailfromrules +a list of assigned senders and designated 'Mail From:' +addresses in the following format: + +12.34.56.:@example.com +12.34.56.78:jffy@example.com,fred@noexample.com +=example.com:@example.com +joe@example.com:joe.stein@example.com + + +Note 1: The addresses are included in a tcpserver +compatible format. + +Note 2: The length of the assigned email 'Mail From:' +addresses is only limited by memory. + +Note 3: All assigned 'Mail From:' addresses have to +include a '@'. Checks are done for spaces. Comments +are allowed. + +Note 4: All addresses are evaluated in lower case. + + +Run bin/qmail-mfrules to construct control/mailfromrules.cdb +out of control/mailfromrules. + + +Return codes +------------ + +In case, the match was not successful, the sending MTA +client receives the following message: + +"553 sorry, invalid sender address specified (#5.7.1)" + +The message can be customized by means of the environment +variable REPLYMAV="texstring" including 'textstring' between +'specified' and the EMSSC code. + + +Others information +------------------ + +Read PROPOSAL.mav. + +Read man qmail-mfrules. +Read man qmail-smtpd. +Read man qmail-control. +Perform qmail-showctl. + + +Erwin Hoffmann, Cologne 2005-04-26. + + + + + + + diff --git a/doc/Old/README.qmq b/doc/Old/README.qmq new file mode 100644 index 0000000..1940cd1 --- /dev/null +++ b/doc/Old/README.qmq @@ -0,0 +1,73 @@ +Qmail Multiple Queue (Option) -- QMQ(0) +--------------------------------------- + +1. What is QMQ ? + +Qmail Multiple Queue -- is an option (of SPAMCONTROL). +SPAMCONTROL is useful on Qmail hosts attached to the +Internet and receiving e-mails, shortly named MTA +(Mail Transfer Agents). +While SPAMCONTROL tries to take control of the +incoming SMTP traffic, QMQ allows you to control +the e-mail communication to -- and from -- the +(downstream) e-mail domains you are responsible for. + +2. How does QMQ work ? + +In addition to standard Qmail (patched with SPAMCONTROL) +to receive e-mails from the Internet, you set up > N < +secondary instances of Qmail to deliver e-mails to your +downstream domains. +The different Qmail instances are typically set up on +one host; the communication from the primary instance to +the secondary is faciliated by QMTP, though SMTP can be +used as well. +While the primary instance is patched with SPAMCONTROL, +all seconderis can be plain (Vanilla) Qmail. +Once the primary Qmail instance receives an e-mail for +a QMQ domain, it will forward the e-mail via QMTP to +one of the secondary instances, which is responsible +for furthter delivery. +This not only will avoid the so-called "Silly Qmail +Syndrom" but will allow you to fine-tune the delivery +conditions and set-up (e.g. Virus/Spam scanners) +for any recipient domain. + +3. How to set up multiple Qmail instances ? + +You are free to set them up. +However, you can use the scheme, I have developed: +a) Modify "conf-qmq" to your needs. + Here, you define the (local) instances by name + and their (QMTP) port numbers. +b) Execute ./qmtpt ..../ . This will raise + - ./qmail/skeleton -- + - ./qmail/source + +4. What is the benefit of QMQ ? + +a) Decoupling: Delivery to domain >i< is independent + of domain >k<. +b) Independent delivery parms and perhaps filters for + any secondary domain. +c) Primary instance does not suffer from "Silly Qmail + Syndrom". +d) Set up of a dedicated Bounce Queue. +e) Thruput is increase by a factor of 10 - 100. + + +5. Consideratons: + +a) Using 'qmail-qstat' practically, very littly + e-mails stay in step 'preprocessed' (on the + primary instance) will be realised. +b) Adjust your delivery channels to your needs. + With QMQ, Qmail will easly flood them up. + + +Erwin Hoffmann +Cologne, 17-08-2007 + + + + diff --git a/doc/Old/README.recipients b/doc/Old/README.recipients new file mode 100644 index 0000000..90a4003 --- /dev/null +++ b/doc/Old/README.recipients @@ -0,0 +1,256 @@ +README - qmail-smtpd RECIPIENTS extension +========================================= + +1. Scope: + +qmail-smtpd accepts messages if the SMTP domain part of +recipient address ("RCPT to: <recip@domain>") matches an +entry in control/rcpthosts or control/morercpthosts.cdb. + +The existence of a mailbox/maildir for the corresponding +SMTP recipient is checked later in the delivery chain. + +In case no Mailbox/Maildir exists, the message is bounced +back to the SMTP sender ("MAIL From: <send@example.com>"). + +For normal SMTP mail traffic thats fine as long as the rate +of undeliverable messages dont exceed 10% and the sender is +'legitmate'; ie. exists. + +Todays situation is different: Spam and Virus attacks with +forged/faked sender addresses to a bunch of random +recipient addresses yield a undeliverable rate up to 90%. + +Worse, the generated bounces will never reach the sender and +a double-bounce is eventually send to the postmaster. + + +2. qmail-smtpd RECIPIENTS: + +The RECIPIENTS extension makes qmail-smtpd aware of acceptable +recipients, which are fetched from an external source. +Which source to query depends on the domain-part of the +recipient address. + +- The recipients are kept either in 'fastforward' compatible + cdbs for quick lookup during the SMTP session, or +- are available by means of a 'checkpassword' compatible + Plugable Authentication Module (PAM). + +The RECIPIENTS mechanism supports natively Qmail's address +extensions (VERP). If a recipient address like 'foo@mydomain.com' +defined, all VERP addresses like 'foo-bar@mydomain.com' are +accepted for SMTP reception. + +The RECIPIENTS lookup is triggered by the recipient domain, thus +is domain-specific. The domain-part of the envelope address +is evaluated in lower case. You can specify which lookup is performed +per domain within control/recipients. Consider the following: + +a) An entry 'example.com' is used to match 'example.com' and + in addition all subdomain addresses '*.example.com'; + depending in addition on 'control/rcpthosts'. +b) An entry '@example.com' serves as exact match for the + domain address. +c) The entry '*' will match all domains for the respective lookup. +d) Reversely, domains flagged as '!domain.com' are not queried + and all recipients for this domain are accepted. +e) A 'fail-open' behaviour can be achieved adding '!*' as last + statement in control/recipients. Thus, emails for domains not + listed in control/recipients will finally be accepted. + +Thus, the RECIPIENTS extension can be used in a 'fail-closed' or +'fail-open' mode for the domains included in control/recipients. +Without including '!*' on the last line, the recipient check is done +'fail-closed', thus if all queries are negative, the incoming email +with this recipient address will be rejected. + +The RECIPIENTS check is done only in a none-RELAYCLIENT case +and after control/rcpthosts, control/morercpthosts.cdb has been +successfully consulted. + +NOTE: The new wilddomain mechanism superseeds the old cdb-only + wilddomain syntax (which is not working anymore). + The PAM should be in your $PATH or referenced with full path. + + +3. Setting up the recipients control file: + +Release 0.5 the RECIPIENTS extension provides a flexible +new syntax to interprete control/recipients on a domain +base, as part of the RCPT TO: envelope address. + +a) Read 'man qmail-smtpd' and 'man qmail-recipients.' + Some additional scripts can be found in doc. + +b) Legacy: + Put 'recipients.cdb' into control/recipients. + This is a backward compatible mode. + +c) Per Domain cdbs: + Put 'example.com:example.cdb' in + control/recipients and you advise the + RECIPIENTS extension to do a per-domain lookup. + +d) Global cdbs: + Use '*:users/recipients.cdb' in + control/recipients. + This is equivalent to (1.). + +e) Per Domain PAM: + Put 'example.com|checkpassword true' + into control/recipients and the RECIPIENT + extension will use the program defined + after the "|" to check the existence of + the provided RCPT TO. + +f) Global PAM: + Put '*|ldapam myldapserver' into + control/recipients and you delegate the entire + verification of the RCPT TO to the program in charge. + +g) Wildcarded domain: + Prepend the domain name with a '!' and + emails for this domain will be entirely accepted: + '!localhost'. + +h) Pass-Thru for unlisted domains: + Use '!*' as last statement in control/recipients. + +Lines in control/recipients starting with a '#' +are not evaluated, thus are treated as comment lines. + + +4. Generating a cdb with recipient addresses: + +a) Build a list of recipients (with full qualified address). +- Use 'qmail-pwd2recipients' to build this list for + local system users. +- Use 'qmail-alias2recipients' to build this list for + qmail alias users (ie. postmaster, root). +- Use 'qmail-users2recipients' to build this list for + qmail users (as per users/assign). +- You can use 'qmail-vpopmail2recipients' for + vpopmail users. + + Verify that list to be found under users/recipients. + If you have a different Qmail home directory, modify the + above scripts. + + You may need to change "localhost" in the above scripts + to the real hostname. + +b) Run qmail-recipients to transform that list into a cdb: + users/recipients.cdb + +c) After the successful generation of the recipients.cdb + you can rename it to your taste. + +d) Edit control/recipients and + include users/recipients.cdb therein. + +e) If you have 'fastforward' cdbs (those which are generated + by 'setforward') you have to place the output somewhere + in a subdirectory under Qmail's home directory and + include those into control/recipients. + + At that time, your control/recipients file may look like: + + mydomain.com:control/mydomain.cdb + users/recipients.cdb + etc/fastforward.cdb + +f) You can add an arbitary number of cdbs to control/recipients. + Any change regarding control/recipients and/or the content + of the cdbs is effective on the fly. + + +5. VERP support + +The RECIPIENTS extension allows now per default VERP support. +The local part of the recipient addresses is truncted AFTER +the character defined as AUTO_BREAK and only the first part +of the address (plus domain) is used for the evaluation. + +a) If you run EZMLM, you have to set up a list of recipient + addresses for all your mailing lists. + +b) Simply put the full qualified list name apppended with the VERP + charcater into the recipients database (or into the LDAP dir). + +c) Sample: If your list is called: + + mylist@example.com + + define + + mylist-@example.com + + This makes VERP addresses distinguishable from normal addresses. + +d) In order to support generic and VERP addresses, you have to + add both address schemes into the recipient database: + + me@example.com + me-@example.com + + +6. Using a checkpassword compatible PAM: + +The checkpassword API is defined in: + + http://cr.yp.to/checkpwd/interface.html + +and typically consists of the string: + + username\0password\0timestamp\0otherdata\0 + +written to file descriptor 3 (FD 3) to be read by the +checkpassword compatible PAM. + +For email address (recipient) verification, we replace + username\0 +with + email-address\0 +ie. + recipient@domain.tld\0 + +The PAM fetches this information and checks for it's +existance in any external resource, for example a LDAP +directory or a SQL database. + +The PAM returns a '0' in case of successful verification, +otherwise a '1'; and perhaps a '111' in case of problems. + +RECIPIENT's checkpassword API allows to enter up to five +additional arguments; which are specific to the PAM. + +The attached PERL ldap_mail.pl serves as a sample. + + +7. Customization: + +The RECIPIENTS extension needs no customization except for +the following circumstances: + +a) You may need to adjust the provided scripts + 'qmail-pwd2recipients', 'qmail-users2recipients', and + 'qmail-alias2recipient' to your need; these are samples. + +b) The script 'qmail-vpopmail2recipients' is contributed + by David Du SERRE-TELMON, pls. check whether it + suits your vpopmail installation. + +c) A phyton script to generate "Recipients" users out of + - /var/qmail/users/assign + - /var/qmail/alias + -/etc/aliases + and the vpopmail's virtual users can be found at: + + http://www.epigenomics.org/software/oss/qmail/create_recipients.py + + Contributed by Robert Sander + + + +Erwin Hoffmann (www.fehcom.de) - Cologne 2009-09-02 diff --git a/doc/Old/README.wildmat b/doc/Old/README.wildmat new file mode 100644 index 0000000..ccfbe0e --- /dev/null +++ b/doc/Old/README.wildmat @@ -0,0 +1,100 @@ +/* THIS FILE IS INCLUDED FOR HISTORICAL REASONS ONLY */ + + +EADME.wildmat.orig Wed Dec 3 11:46:31 1997 +--- README.wildmat Wed Dec 3 11:53:33 1997 +*************** +*** 0 **** +--- 1,50 ---- ++ wilmat patch version 0.2 for qmail 1.01 ++ Mark Delany <markd@mira.net.au> ++ 19971203 ++ ++ Changes: ++ -------- ++ 0.1 Initial code ++ 0.2 Fixed buglet relating to systems that had no badmailfrom file ++ but do have a badmailpattern file ++ ++ While the 'badmailfrom' provides some ability to block spam it is ++ fairly restricted as the match must be exact on either the full string ++ or the domain. This means that it's very difficult to block the ++ 1234567@aol.com type addresses that some spammers are employing as you ++ potentially require a large number of entries in 'badmailfrom'. ++ ++ This patch provides the ability to use simple patterns to reject mail ++ from unwanted envelope sender addresses. Naturally all such methods ++ are of limited use against spam as a determined spammer cannot be ++ stopped on the current Internet, but it does help until the time comes ++ that we can really stop spammers. ++ ++ The wildmat patch introduces a new control file called ++ 'badmailpatterns' and is used by qmail-smtpd in conjunction with ++ 'badmailfrom'. You should continue to use 'badmailfrom' when you can ++ as this is much more CPU-efficient than 'badmailpatterns'. ++ ++ For those familiar with INN, the wildmat patch uses the wildmat() ++ routine out of INN and evaluates in the same way. Namely that the ++ envelope sender is pushed thru all patterns and the final match or ++ non-match is used to determine whether to reject the mail. It's ++ implemented this way so that 'not' patterns work. ++ ++ Here is a sample 'badmailpatterns' file: ++ ++ *@earthlink.net ++ !fred@earthlink.net ++ [0-9][0-9][0-9][0-9][0-9][0-9]@[0-9][0-9][0-9][0-9].com ++ answerme@save* ++ ++ This file stops all mail from Earthlink except from ++ fred@earthlink.net. It also stops all mail with addresses like: ++ 123456@1234.com and answerme@savetrees.com ++ ++ This patch does not update the documentation or qmail-showctl. ++ ++ Thanks to Rich Salz for providing wildmat.c by way of the INN ++ distribution. wildmat.c is fast, small and completely self-contained. ++ ++ -- +*** wildmat.c.orig Wed Dec 3 11:46:31 1997 +--- wildmat.c Wed Dec 3 11:46:31 1997 +*************** +*** 0 **** +--- 1,172 ---- ++ /* $Revision: 1.1 $ ++ ** ++ ** Do shell-style pattern matching for ?, \, [], and * characters. ++ ** Might not be robust in face of malformed patterns; e.g., "foo[a-" ++ ** could cause a segmentation violation. It is 8bit clean. ++ ** ++ ** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986. ++ ** Rich $alz is now <rsalz@osf.org>. ++ ** April, 1991: Replaced mutually-recursive calls with in-line code ++ ** for the star character. ++ ** ++ ** Special thanks to Lars Mathiesen <thorinn@diku.dk> for the ABORT code. ++ ** This can greatly speed up failing wildcard patterns. For example: ++ ** pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-* ++ ** text 1: -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1 ++ ** text 2: -adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1 ++ ** Text 1 matches with 51 calls, while text 2 fails with 54 calls. Without ++ ** the ABORT code, it takes 22310 calls to fail. Ugh. The following ++ ** explanation is from Lars: ++ ** The precondition that must be fulfilled is that DoMatch will consume ++ ** at least one character in text. This is true if *p is neither '*' nor ++ ** '\0'.) The last return has ABORT instead of FALSE to avoid quadratic ++ ** behaviour in cases like pattern "*a*b*c*d" with text "abcxxxxx". With ++ ** FALSE, each star-loop has to run to the end of the text; with ABORT ++ ** only the last one does. ++ ** ++ ** Once the control of one instance of DoMatch enters the star-loop, that ++ ** instance will return either TRUE or ABORT, and any calling instance ++ ** will therefore return immediately after (without calling recursively ++ ** again). In effect, only one star-loop is ever active. It would be ++ ** possible to modify the code to maintain this context explicitly, ++ ** eliminating all recursive calls at the cost of some complication and ++ ** loss of clarity (and the ABORT stuff seems to be unclear enough by ++ ** itself). I think it would be unwise to try to get this into a ++ ** released version unless you have a good test data base to try it out ++ ** on. ++ */ |