diff options
author | David Bremner <bremner@debian.org> | 2017-11-11 08:46:16 -0400 |
---|---|---|
committer | David Bremner <bremner@debian.org> | 2017-11-11 08:46:16 -0400 |
commit | ddd3f417602bdd5fd55b741900f9450402c6ad02 (patch) | |
tree | 541c8e8e99eff11f58504975dc782d7ee931598b |
Import nullmailer_2.1.orig.tar.gz
[dgit import orig nullmailer_2.1.orig.tar.gz]
178 files changed, 32984 insertions, 0 deletions
@@ -0,0 +1 @@ +Bruce Guenter <bruce@untroubled.org> @@ -0,0 +1,4 @@ +If you find anything in these programs that you would consider a bug, +please report it immediately to: + Bruce Guenter <bruce@untroubled.org> +Thank you! @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..f160aaf --- /dev/null +++ b/ChangeLog @@ -0,0 +1,4795 @@ +commit 1a544303beca771ab4d9c90703934d9897eafbe4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Oct 25 17:36:41 2017 -0600 + + Bump copyright year to 2017 + + lib/address-old.cc | 2 +- + lib/address.cc | 2 +- + lib/base64.cc | 2 +- + lib/canonicalize.cc | 2 +- + lib/cli++/clitest.cc | 2 +- + lib/cli++/main.cc | 2 +- + lib/cli++/messages.cc | 2 +- + lib/config_path.cc | 2 +- + lib/config_read.cc | 2 +- + lib/config_readint.cc | 2 +- + lib/config_readlist.cc | 2 +- + lib/config_syserr.cc | 2 +- + lib/errcodes.cc | 2 +- + lib/fdbuf/fdbuf.cc | 2 +- + lib/fdbuf/fdbuf.h | 2 +- + lib/fdbuf/fdbuf_copy.cc | 2 +- + lib/fdbuf/fdibuf.cc | 2 +- + lib/fdbuf/fdibuf.h | 2 +- + lib/fdbuf/fdibuf_mystring.cc | 2 +- + lib/fdbuf/fdibuf_netstring.cc | 2 +- + lib/fdbuf/fdobuf.cc | 2 +- + lib/fdbuf/fdobuf.h | 2 +- + lib/fdbuf/fdobuf_chownmod.cc | 2 +- + lib/fdbuf/fdobuf_seek.cc | 2 +- + lib/fdbuf/fdobuf_signed.cc | 2 +- + lib/fdbuf/fdobuf_unsigned.cc | 2 +- + lib/fdbuf/tlsibuf.cc | 2 +- + lib/fdbuf/tlsibuf.h | 2 +- + lib/fdbuf/tlsobuf.cc | 2 +- + lib/fdbuf/tlsobuf.h | 2 +- + lib/forkexec.cc | 2 +- + lib/hostname.cc | 2 +- + lib/makefield.cc | 2 +- + lib/mystring/count.cc | 2 +- + lib/mystring/iter.cc | 2 +- + lib/mystring/iter.h | 2 +- + lib/mystring/join.h | 2 +- + lib/mystring/mystring.h | 2 +- + lib/mystring/rep.h | 2 +- + lib/selfpipe.cc | 2 +- + lib/setenv.cc | 2 +- + lib/tcpconnect.cc | 2 +- + protocols/protocol.cc | 2 +- + protocols/qmqp.cc | 2 +- + protocols/smtp.cc | 2 +- + protocols/tls_gnutls.cc | 2 +- + protocols/tls_none.cc | 2 +- + src/dsn.cc | 2 +- + src/inject.cc | 2 +- + src/mailq.cc | 2 +- + src/queue.cc | 2 +- + src/send.cc | 2 +- + src/sendmail.cc | 2 +- + src/smtpd.cc | 2 +- + 54 files changed, 54 insertions(+), 54 deletions(-) + +commit be41e8eeb1bab4ce22299ff388cbb825ce09b41e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 24 11:00:45 2017 -0600 + + lib/cli++: Fix build breakages from previous patch to cli++ + + lib/cli++/cli++topod.pl | 2 +- + lib/cli++/main.cc | 5 +++-- + 2 files changed, 4 insertions(+), 3 deletions(-) + +commit 70af22a74be3f70cb3a4696c86ee04c0ed446968 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 24 09:17:38 2017 -0600 + + NEWS: Add more notes and thanks + + NEWS | 5 +++++ + 1 file changed, 5 insertions(+) + +commit c739463519ad0265488cb457630bd839ac1f003d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 24 09:02:25 2017 -0600 + + doc: Add man pages for mailq and nullmailer-smtpd + + doc/mailq.1 | 19 +++++++++++++++++++ + doc/nullmailer-smtpd.1 | 26 ++++++++++++++++++++++++++ + doc/sendmail.1 | 1 + + 3 files changed, 46 insertions(+) + create mode 100644 doc/mailq.1 + create mode 100644 doc/nullmailer-smtpd.1 + +commit f8ba4dba5ea5b3207d83f5c8cbf5644e36f37090 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 24 08:55:24 2017 -0600 + + NEWS: Add note about previous time fix + + NEWS | 3 +++ + 1 file changed, 3 insertions(+) + +commit 6ef3727a86583d1ae60f1b2083c84aa6b2c6c541 +Author: Felix Lechner <felix.lechner@lease-up.com> +Date: Sun Oct 22 06:13:23 2017 -0700 + + On architectures where the type (time_t) resolves to (ulong), + command line arguments to 'dsn' are not processed correctly. The + (void) pointer passed to lib/cli++/main.cc is cast to + (unsigned int) instead of (ulong). On 64-bit little endian + architectures such as amd64 this is not readily apparent as long + as the higher bits were initialized, but it causes grave errors + on big-endian architectures such as Debian's powerpc or s390x. + + This patch processes the timestamps given on the command line + correctly. + + lib/cli++/cli++.h | 2 +- + lib/cli++/main.cc | 17 ++++++++++------- + lib/config_readint.cc | 6 ++++-- + src/dsn.cc | 6 +++--- + 4 files changed, 18 insertions(+), 13 deletions(-) + +commit 18fcc92801f9b0a00fdf1da23e8f3e12dab4789d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Oct 23 20:55:14 2017 -0600 + + test: Fix some potential races by waiting for subprocesses + + NEWS | 3 +++ + test/functions.in | 3 +++ + test/tests/protocols | 2 -- + 3 files changed, 6 insertions(+), 2 deletions(-) + +commit 5fd6be940792553ce7d9826dc85f9f4813e3bcaa +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Oct 23 20:48:45 2017 -0600 + + lib/tcpconnect.cc: Clarify logic srrounding source addresses + + If no address could be used to bind the source address, the resulting + error code from tcpconnect would be incorrect (temporary gethostbyname + failure). This rewrites it to a more sensible failure to bind source. + + NEWS | 3 +++ + lib/tcpconnect.cc | 10 +++++++++- + test/tests/protocols | 4 ++-- + 3 files changed, 14 insertions(+), 3 deletions(-) + +commit 6c937ce0243019b5891ecd3840ed2d9bf0a155be +Author: Josh Soref <jsoref@users.noreply.github.com> +Date: Thu Oct 19 05:05:10 2017 +0000 + + spelling: succeeded + + lib/address-old.cc | 2 +- + lib/address.cc | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 6466a0d6d8ae7b792dea36d9a694e82d52c14370 +Author: Josh Soref <jsoref@users.noreply.github.com> +Date: Thu Oct 19 05:04:20 2017 +0000 + + spelling: qualified + + doc/nullmailer-dsn.1 | 2 +- + doc/nullmailer-inject.1 | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 1b7c4cc6afe1334d094fd2c2b5c29fe6aaae393b +Author: Josh Soref <jsoref@users.noreply.github.com> +Date: Thu Oct 19 05:04:10 2017 +0000 + + spelling: privileged + + HOWTO | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit a2232df7cbda9dc3f8b9dfa7b529a721d66b31b4 +Author: Josh Soref <jsoref@users.noreply.github.com> +Date: Thu Oct 19 05:02:57 2017 +0000 + + spelling: needed + + ChangeLog.old | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 11b393d1ef77d3330ec5a9baa24367f4754af1ca +Author: Josh Soref <jsoref@users.noreply.github.com> +Date: Thu Oct 19 05:00:36 2017 +0000 + + spelling: escalation + + lib/config_path.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ed19003083b7ab5de1cffe2e474a15c19ee5407e +Author: Josh Soref <jsoref@users.noreply.github.com> +Date: Thu Oct 19 05:00:21 2017 +0000 + + spelling: email + + protocols/qmqp.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit fbdd0ba6613188ab375f6bdbb5747d18b583b90c +Merge: a85d249 178b025 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Sep 28 11:53:30 2017 -0600 + + Merge branch 'empty-sender' of https://github.com/wiedi/nullmailer + +commit a85d2498a27a31897b0364041eaec6cd07496309 +Merge: cdbdf35 cce9a89 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Sep 28 11:50:53 2017 -0600 + + Merge branch 'tls_anon_auth' of git://github.com/uffejakobsen/nullmailer + +commit cdbdf35d370168b23f5e34f486da927f26ba601a +Author: Mihai Moldovan <ionic@ionic.de> +Date: Tue Sep 26 15:21:20 2017 +0200 + + lib/argparse: fix parsing of shell-like quoting structures when encountered mid-string. + + Includes test cases for both double and single quotes. + + Fixes: https://github.com/bruceg/nullmailer/issues/45 + + lib/argparse.cc | 7 ++++--- + test/argparse-test.cc | 2 ++ + 2 files changed, 6 insertions(+), 3 deletions(-) + +commit 7587abe5f2252af94dbee3000875dd239f0b9eb0 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Sep 27 07:18:09 2017 -0600 + + lib/mergelib.sh: Use configured AR/RANLIB also in mergelib.sh + + Fixes: #41 + + lib/mergelib.sh | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit a16964649311955e3d9201f40a2b2b07828497f7 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Sep 27 07:16:25 2017 -0600 + + INSTALL: Add note to run autogen.sh before configure + + Fixes: #40 + + INSTALL | 3 +++ + 1 file changed, 3 insertions(+) + +commit 178b025932ca8bf7a3f1f0004fc7c227b574d223 +Author: Sebastian Wiedenroth <wiedi@frubar.net> +Date: Tue Jun 13 13:20:24 2017 +0200 + + sendmail: explicitly pass along empty sender + + src/sendmail.cc | 48 ++++++++++++++++++++++++++++-------------------- + 1 file changed, 28 insertions(+), 20 deletions(-) + +commit ac63ab24326266172d289896cceda534dc0bb84c +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Mar 3 14:16:18 2017 -0600 + + Bump version to 2.1 + + NEWS | 11 +++++++++-- + README | 6 +++--- + configure.ac | 2 +- + 3 files changed, 13 insertions(+), 6 deletions(-) + +commit aa3adbfcc7852b3c2cc89fbb8ebd3f819609b4ec +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 1 14:54:40 2017 -0600 + + test: Fix test for nullmailer-send bounce message output + + test/tests/send | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c973edcd8150dfdbd4ae0451df003a046015f06d +Author: Uffe Jakobsen <uffe@uffe.org> +Date: Thu May 5 11:52:54 2016 +0200 + + autogen.sh: test and create phony ChangeLog for automake to succeed + + autogen.sh | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 2dec8d22e1f3ea926069899ed20707669f2d3bf9 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 1 12:38:03 2017 -0600 + + nullmailer-dsn: Restore the --max-lines options and fix tests + + src/dsn.cc | 10 ++++++++-- + test/tests/dsn | 2 +- + 2 files changed, 9 insertions(+), 3 deletions(-) + +commit e4cc153582dc1acf5515108f063245e2f001f68a +Author: klemens <ka7@github.com> +Date: Thu Apr 14 22:03:35 2016 +0200 + + spelling fix, as of lintian.debian.org + + doc/nullmailer-send.8 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 30d4097db6dfb3b84459da1f5ae73db8305a054f +Author: Mike Frysinger <vapier@gentoo.org> +Date: Mon Mar 7 16:36:11 2016 -0500 + + enable transparent large file support + + Historically LFS mattered only to open/read large files. A few programs + here use open/seek, but not generally on files that are large. However, + LFS also applies to stat which procps does in a bunch of places -- some + filesystems have 64bit inodes and attempts to do a 32bit stat will throw + an error. + + Enable transparent LFS everywhere to avoid this. + + configure.ac | 1 + + 1 file changed, 1 insertion(+) + +commit 2bba417e4171ce0e90f70047431a8ba74f9a598b +Author: W. Trevor King <wking@tremily.us> +Date: Thu Sep 15 11:36:30 2016 -0700 + + doc: Fix "defauldomain" -> "defaultdomain" typos + + doc/nullmailer-dsn.1 | 2 +- + doc/nullmailer-inject.1 | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit babec3b1054a370b18fd156b1a60490bd952783e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 1 09:49:48 2017 -0600 + + nullmailer-inject: Drop leading "From " lines + + This fixes problems with some broken mail senders that mistakenly add + them. Patch suggested by Sebastian Wiedenroth <wiedi@frubar.net> + + NEWS | 2 ++ + src/inject.cc | 5 +++++ + test/tests/inject/from_ | 10 ++++++++++ + 3 files changed, 17 insertions(+) + create mode 100644 test/tests/inject/from_ + +commit 541e456a6ba31ecc39c1e19c3121f81d8f6da26f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Feb 28 17:12:04 2017 -0600 + + lib/mystring: Add mystring::starts_with methods + + lib/mystring/Makefile.am | 1 + + lib/mystring/mystring.h | 4 ++++ + lib/mystring/starts_with.cc | 17 +++++++++++++++++ + 3 files changed, 22 insertions(+) + create mode 100644 lib/mystring/starts_with.cc + +commit f50b29ff16101941e5bfb3d3774c0d3cf1997b0d +Author: Sebastian Wiedenroth <wiedi@frubar.net> +Date: Mon Nov 14 22:52:02 2016 +0000 + + fix build on illumos + + lib/tcpconnect.cc | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +commit 2a33bea069c69199eda8e9ded26b33f8caeeba3d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Feb 28 13:38:25 2017 -0600 + + nullmailer-dsn: Default to copying only the header instead of whole message + + doc/nullmailer-dsn.1 | 2 +- + src/dsn.cc | 8 ++------ + 2 files changed, 3 insertions(+), 7 deletions(-) + +commit 05469b7b2c91d626e3c451fdf2401d0568cca9a1 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Feb 28 13:32:23 2017 -0600 + + lib/forkexec.h: Add missing #include <signal.h> + + lib/forkexec.h | 1 + + 1 file changed, 1 insertion(+) + +commit cce9a89f138d943fa70a37e166a8b04d276ec5b3 +Author: Uffe Jakobsen <uffe@uffe.org> +Date: Thu May 5 13:41:14 2016 +0200 + + Implement TLS anonymous authentication in smtp + + configure.ac | 2 ++ + doc/nullmailer-send.8 | 8 ++++++++ + protocols/protocol.cc | 3 ++- + protocols/protocol.h | 2 +- + protocols/tls_gnutls.cc | 43 +++++++++++++++++++++++++++++++++++++++++-- + 5 files changed, 54 insertions(+), 4 deletions(-) + +commit 6567de3d2f5936692fd2e272688386efa95f11fb +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 22 11:02:45 2016 -0600 + + Add a trivial autogen.sh script, to generate autoconf/automake files + + autogen.sh | 5 +++++ + 1 file changed, 5 insertions(+) + create mode 100644 autogen.sh + +commit 471b1b42c931129f78a5054f323223549d0ab268 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 22 10:51:09 2016 -0600 + + Update dates in sources and README + + README | 4 ++-- + lib/address-old.cc | 2 +- + lib/address.cc | 2 +- + lib/base64.cc | 2 +- + lib/canonicalize.cc | 2 +- + lib/cli++/clitest.cc | 2 +- + lib/cli++/main.cc | 2 +- + lib/cli++/messages.cc | 2 +- + lib/config_read.cc | 2 +- + lib/config_readint.cc | 2 +- + lib/config_readlist.cc | 2 +- + lib/config_syserr.cc | 2 +- + lib/errcodes.cc | 2 +- + lib/fdbuf/fdbuf.cc | 2 +- + lib/fdbuf/fdbuf.h | 2 +- + lib/fdbuf/fdbuf_copy.cc | 2 +- + lib/fdbuf/fdibuf.cc | 2 +- + lib/fdbuf/fdibuf.h | 2 +- + lib/fdbuf/fdibuf_mystring.cc | 2 +- + lib/fdbuf/fdibuf_netstring.cc | 2 +- + lib/fdbuf/fdobuf.cc | 2 +- + lib/fdbuf/fdobuf.h | 2 +- + lib/fdbuf/fdobuf_chownmod.cc | 2 +- + lib/fdbuf/fdobuf_seek.cc | 2 +- + lib/fdbuf/fdobuf_signed.cc | 2 +- + lib/fdbuf/fdobuf_unsigned.cc | 2 +- + lib/fdbuf/tlsibuf.cc | 2 +- + lib/fdbuf/tlsibuf.h | 2 +- + lib/fdbuf/tlsobuf.cc | 2 +- + lib/fdbuf/tlsobuf.h | 2 +- + lib/hostname.cc | 2 +- + lib/makefield.cc | 2 +- + lib/mystring/count.cc | 2 +- + lib/mystring/iter.cc | 2 +- + lib/mystring/iter.h | 2 +- + lib/mystring/join.h | 2 +- + lib/mystring/mystring.h | 2 +- + lib/mystring/rep.h | 2 +- + lib/selfpipe.cc | 2 +- + lib/setenv.cc | 2 +- + lib/tcpconnect.cc | 2 +- + protocols/protocol.cc | 2 +- + protocols/qmqp.cc | 2 +- + protocols/smtp.cc | 2 +- + protocols/tls_gnutls.cc | 2 +- + protocols/tls_none.cc | 2 +- + src/dsn.cc | 2 +- + src/inject.cc | 2 +- + src/mailq.cc | 2 +- + src/queue.cc | 2 +- + src/send.cc | 2 +- + src/sendmail.cc | 2 +- + src/smtpd.cc | 2 +- + 53 files changed, 54 insertions(+), 54 deletions(-) + +commit 1971c4506e336d60439ae4539b0742cea2a648fb +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 22 10:35:22 2016 -0600 + + Remove done items from the TODO list + + TODO | 14 ++------------ + 1 file changed, 2 insertions(+), 12 deletions(-) + +commit 9819b7b97b42255e9f8f25d951d9ac91989c0066 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 21 16:08:03 2016 -0600 + + Add a "check" make target and fix distcheck problems + + Makefile.am | 3 --- + test/Makefile.am | 18 +++++++++--------- + test/functions.in | 22 +++++++++++++++++----- + test/{runtests.in => runtests} | 9 +++------ + test/tests/dsn | 2 +- + test/tests/mailq | 4 ++-- + test/tests/send | 2 +- + test/tests/smtpd | 1 - + 8 files changed, 33 insertions(+), 28 deletions(-) + rename test/{runtests.in => runtests} (63%) + mode change 100644 => 100755 + +commit 80260ff8cf0761bfa50598fe166ca965afaa3a85 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 21 16:45:56 2016 -0600 + + Rework path handling to allow for testing anywhere + + This introduces a $NULLMAILER_TEST_PREFIX environment variable that may + be used to override built-in paths to programs, the queue, etc. + + In particular: + + $NULLMAILER_TEST_PREFIX/bin is used for programs + + $NULLMAILER_TEST_PREFIX/conf is used for config files + + $NULLMAILER_TEST_PREFIX/queue is used for the queue directories + + $NULLMAILER_TEST_PREFIX/protocols is used for protocol programs + + $NULLMAILER_TEST_PREFIX/sbin is used for system programs (nullmailer-queue) + + These overrides are not used by programs such as mailq and + nullmailer-queue when they are running setuid to avoid privilege + escalation problems. + + lib/Makefile.am | 3 ++- + lib/{config_readint.cc => config_path.cc} | 40 ++++++++++++++++++++++++------- + lib/config_read.cc | 3 +-- + lib/config_readlist.cc | 3 +-- + lib/configio.h | 3 +++ + lib/defines.h | 11 +++++---- + lib/forkexec.cc | 21 +++++++--------- + lib/forkexec.h | 3 ++- + lib/make_defines.sh | 13 ++++------ + src/mailq.cc | 14 ++++++----- + src/queue.cc | 20 +++++++++++----- + src/send.cc | 16 +++++++++---- + src/sendmail.cc | 5 ++-- + test/Makefile.am | 2 +- + test/functions.in | 17 +++++++------ + test/runtests.in | 9 +------ + test/tests/inject/queue | 9 +++---- + test/tests/mailq | 4 ++-- + test/tests/queue/rewrite | 8 +++---- + test/tests/send | 4 ++-- + 20 files changed, 120 insertions(+), 88 deletions(-) + copy lib/{config_readint.cc => config_path.cc} (57%) + +commit 0f4f095ff406eb8ece43732d61ada0ca4f501ec5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 21 16:30:27 2016 -0600 + + dsn: Add controls to limit how much of the message to copy + + doc/nullmailer-dsn.1 | 14 ++++++++++++++ + src/dsn.cc | 19 ++++++++++++++++--- + test/tests/dsn | 22 +++++++++++++++++++++- + 3 files changed, 51 insertions(+), 4 deletions(-) + +commit 0aa713238549bafcae6d5a1d805b69e3396b4458 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 21 12:45:08 2016 -0600 + + Move spool directory to /var/spool/nullmailer, like other MTAs + + Makefile.am | 2 +- + NEWS | 2 ++ + doc/nullmailer-queue.8 | 6 +++--- + doc/nullmailer-send.8 | 6 +++--- + lib/Makefile.am | 2 +- + scripts/nullmailer.service | 4 ++-- + spec | 11 ++++++----- + test/functions.in | 2 +- + test/tests/inject/queue | 8 ++++---- + test/tests/queue/rewrite | 4 ++-- + test/tests/smtpd | 2 +- + 11 files changed, 26 insertions(+), 23 deletions(-) + +commit 1ff9b88936b4a6463ca0813361f8e88f811d2629 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 21 11:41:52 2016 -0600 + + Fix problems found by "make distcheck" + + Makefile.am | 7 ++++--- + lib/Makefile.am | 16 +++++++--------- + lib/cli++/Makefile.am | 2 +- + lib/fdbuf/Makefile.am | 2 +- + lib/mystring/Makefile.am | 2 +- + protocols/Makefile.am | 2 +- + protocols/protocol.cc | 2 +- + src/Makefile.am | 2 +- + src/smtpd.cc | 2 +- + test/Makefile.am | 8 ++++---- + 10 files changed, 22 insertions(+), 23 deletions(-) + +commit 8f5cd1d90861d0a2133c2112c157b01138645f67 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 21 08:37:12 2016 -0600 + + test: Drop use of $PWD in tests + + test/functions.in | 2 +- + test/tests/send | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit eab2761bfaccf4fa1da39d33c1534236ffc1d725 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 20 15:29:58 2016 -0600 + + test: Move temporary directory out of test + + .gitignore | 2 +- + test/runtests.in | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +commit 54314296ed1753e83782e1856c14ca5615418331 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 20 15:18:17 2016 -0600 + + dsn: Allow for directing all bounces to a fixed address + + doc/nullmailer-dsn.1 | 6 +++++- + src/dsn.cc | 5 ++++- + test/tests/dsn | 7 ++++++- + 3 files changed, 15 insertions(+), 3 deletions(-) + +commit 481224fb15502629b7f688ed4c66cf6feefd6fc7 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 20 15:07:46 2016 -0600 + + dsn: Fix Content-Type header and add a test + + src/dsn.cc | 2 +- + test/functions.in | 15 ++++++++++ + test/tests/dsn | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 99 insertions(+), 1 deletion(-) + create mode 100644 test/tests/dsn + +commit a0d1b330ce00fa22ee469d03f50930f4a65b3243 +Merge: a8261e0 97f0512 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 20 09:20:07 2016 -0600 + + Merge branch 'bounce' + +commit a8261e028286a719b4ff4e81a2ce9e39ce4216ae +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 20 06:47:14 2016 -0600 + + test: Fix up location of log for send test + + test/tests/send | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +commit 958b9015d0f2f0bb0995197afaaceda6a061867a +Merge: 9ac7c4d 9e1b54f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 19 09:27:44 2016 -0600 + + Merge branch 'log-envelope' + +commit 97f05128cdc483387e7826c4a9dd9f174910329c +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 19 08:14:13 2016 -0600 + + send: Catch the output from protocols for the DSN diagnostic codes + + lib/forkexec.h | 1 + + protocols/protocol.cc | 6 ++++-- + src/send.cc | 52 +++++++++++++++++++++++++++++++++++++++++++-------- + test/tests/send | 12 ++++++++++-- + 4 files changed, 59 insertions(+), 12 deletions(-) + +commit 56e90a1774b81462c5ca738d9a3dcc747d77d2c5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Jan 18 21:31:22 2016 -0600 + + doc: Updated diagram + + doc/DIAGRAM | 25 +++++++++++++++++++++++++ + doc/Makefile.am | 2 +- + doc/diagram | 21 --------------------- + spec | 2 +- + 4 files changed, 27 insertions(+), 23 deletions(-) + create mode 100644 doc/DIAGRAM + delete mode 100644 doc/diagram + +commit aaa77ab70dd499f2e768108ed9e3e406271cf787 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Jan 18 20:58:22 2016 -0600 + + doc: Add man page for nullmailer-dsn to Makefile + + doc/Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +commit c347e63bcec01e28774d4050a89382e60dff29bf +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Jan 18 20:50:47 2016 -0600 + + send: Ignore dotfiles in the queue + + src/send.cc | 2 ++ + 1 file changed, 2 insertions(+) + +commit 4dc827163034eb721c6f1e743bfaa1a447d64a8e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Jan 18 20:49:51 2016 -0600 + + send: Add support for generating bounce messages + + NEWS | 2 +- + doc/nullmailer-send.8 | 6 ++++-- + lib/forkexec.cc | 11 ++++++++--- + lib/forkexec.h | 1 + + src/send.cc | 25 ++++++++++++++++++++++--- + test/functions.in | 3 ++- + test/tests/send | 37 +++++++++++++++++++++++++++++++------ + 7 files changed, 69 insertions(+), 16 deletions(-) + +commit b83af86a6fe9f308e51ed9528df700acce1626fd +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Jan 18 12:04:41 2016 -0600 + + lib: Add program_path function for calculating program names + + lib/forkexec.cc | 24 +++++++++++++++--------- + lib/forkexec.h | 3 +++ + src/sendmail.cc | 8 +++----- + 3 files changed, 21 insertions(+), 14 deletions(-) + +commit 84e4916f1a3fed45ac55611b342f661e9b0c7644 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Jan 18 11:39:45 2016 -0600 + + doc: Add notes to -send man page about the failed queue, and other fixes + + doc/nullmailer-send.8 | 53 +++++++++++++++++++++++++++++++++------------------ + 1 file changed, 34 insertions(+), 19 deletions(-) + +commit 58a361cad086e3f71dbb5152878d174f5616ac59 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Jan 18 09:00:30 2016 -0600 + + lib: Add support for generic FD redirection in fork_exec + + lib/forkexec.cc | 76 +++++++++++++++++++++++++++++++-------------------------- + lib/forkexec.h | 11 +++++---- + src/inject.cc | 6 +++-- + src/send.cc | 7 +++--- + src/smtpd.cc | 13 +++++----- + 5 files changed, 63 insertions(+), 50 deletions(-) + +commit de98c6ccc2a3aef3c5302e1ce52ecb6ac53c5fbf +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Jan 18 09:31:29 2016 -0600 + + lib: Add autoclose_pipe class to simplify use of pipes + + lib/autoclose.h | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +commit 28f6d9561599365f00c5a0a25166e45a2bd1334d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 15 15:40:55 2016 -0600 + + send: Use fork_exec to execute the protocol + + lib/forkexec.cc | 17 +++++++++++++--- + lib/forkexec.h | 3 +++ + src/send.cc | 60 +++++++++++++++++---------------------------------------- + 3 files changed, 35 insertions(+), 45 deletions(-) + +commit a712b0845da4ee3a1fc7b801713e15c3c193eb01 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 15 15:40:31 2016 -0600 + + lib: Add support for redirecting a (single) FD in fork_exec + + lib/forkexec.cc | 7 ++++++- + lib/forkexec.h | 2 +- + 2 files changed, 7 insertions(+), 2 deletions(-) + +commit 5850a49ade78d36ce33d70c28198b9cf2fb8fbdd +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 15 11:40:38 2016 -0600 + + lib: Add fork_exec wrapper class for launching sub-programs + + lib/Makefile.am | 1 + + lib/autoclose.h | 7 ++- + lib/forkexec.cc | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + lib/forkexec.h | 32 +++++++++++++ + src/inject.cc | 108 +++++++++++++------------------------------- + src/send.cc | 1 + + src/smtpd.cc | 63 +++++--------------------- + 7 files changed, 217 insertions(+), 131 deletions(-) + create mode 100644 lib/forkexec.cc + create mode 100644 lib/forkexec.h + +commit 2e3075039213af49353a6bff781fddba1c601300 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 16:27:26 2016 -0600 + + lib: Add helper to close FDs at function return + + lib/autoclose.h | 25 +++++++++++++++++++++++++ + src/queue.cc | 7 +++---- + src/send.cc | 7 +++---- + src/smtpd.cc | 37 +++++++++++++++++++------------------ + 4 files changed, 50 insertions(+), 26 deletions(-) + create mode 100644 lib/autoclose.h + +commit ecd433c8311c08cc328422f8d98dffd8a4a0f21d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 14:53:35 2016 -0600 + + doc: Added documentation for -dsn + + NEWS | 2 + + doc/nullmailer-dsn.1 | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ + doc/nullmailer-inject.1 | 16 ++++---- + doc/nullmailer.7 | 11 ++--- + 4 files changed, 123 insertions(+), 13 deletions(-) + create mode 100644 doc/nullmailer-dsn.1 + +commit a5917e4b0a5cde4709da6bcdd2bc0f04700f65eb +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 14:52:44 2016 -0600 + + dsn: Generalized --smtp-diagnostic option to --diagnostic-code + + src/dsn.cc | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +commit 3bf1ff020640d74ab292e57858c2f9c0cd86d378 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 12:07:58 2016 -0600 + + Add NEWS note about -send changes and bump version to 2.00 + + NEWS | 5 ++++- + README | 2 +- + configure.ac | 2 +- + 3 files changed, 6 insertions(+), 3 deletions(-) + +commit 9e1b54fa242abf87e4170ac819f8a0e3edcc2799 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 19 09:25:39 2016 -0600 + + send: Also log the Message-Id header + + src/send.cc | 16 +++++++++++----- + test/tests/send | 2 ++ + 2 files changed, 13 insertions(+), 5 deletions(-) + +commit b53e20452fba446b8fb81662b053e7256b20fada +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 16:36:59 2016 -0600 + + send: Add support for logging envelope contents + + NEWS | 2 ++ + src/send.cc | 36 +++++++++++++++++++++++++++++++++--- + test/tests/send | 5 +++++ + 3 files changed, 40 insertions(+), 3 deletions(-) + +commit 9ac7c4d60a730bb3cd83cb727468e9455c0bbfd1 +Merge: 861d78f d3afb60 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Jan 18 09:32:32 2016 -0600 + + Merge branch 'bind-source' + +commit 861d78f55a2e82aa13792300d4a7502fb056b05a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 15 17:15:44 2016 -0600 + + Add "tests" make target to simplify testing + + Makefile.am | 3 +++ + 1 file changed, 3 insertions(+) + +commit 01eebcc594ab3c86fcbad38abdecd0ee9d546e0b +Merge: be238ba 0f358eb +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 15 17:14:35 2016 -0600 + + Merge branch 'empty-sender' + +commit d3afb601c93e36cfd0cbf5b0962baacc1e88e956 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 15 16:36:44 2016 -0600 + + protocols: Add support for binding the source address + + NEWS | 2 ++ + doc/nullmailer-send.8 | 3 +++ + lib/connect.h | 2 +- + lib/errcodes.cc | 1 + + lib/errcodes.h | 1 + + lib/tcpconnect.cc | 62 +++++++++++++++++++++++++++++++++++++++++++-------- + protocols/protocol.cc | 5 ++++- + test/tests/protocols | 9 ++++++++ + 8 files changed, 74 insertions(+), 11 deletions(-) + +commit 5e91ef61f7ec0638d8d7aa42da328161fa232aa8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 15 16:01:12 2016 -0600 + + lib: Move getaddrinfo bits out of tcpconnect function + + lib/tcpconnect.cc | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +commit 4431872a97c331dfe363c1e492dfe3da75063f00 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 15 16:50:29 2016 -0600 + + lib: Drop use of mystring for tcpconnect hostname parameter + + lib/connect.h | 4 +--- + lib/tcpconnect.cc | 10 +++++----- + protocols/protocol.cc | 1 + + 3 files changed, 7 insertions(+), 8 deletions(-) + +commit 798daf0b27cf56fea497ef125c440f81133a0bfc +Merge: 9bb74bc 2cb6ea2 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 11:40:01 2016 -0600 + + Merge branch 'master' into bounce + +commit be238baba9de88dd71bd3217494fe1c8c263427a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 12:24:52 2016 -0600 + + doc: -inject prints diagnostics to stderr not stdout + + doc/nullmailer-inject.1 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2cb6ea21c0006cf0aa4ab4041616f1b394eb754e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 11:30:43 2016 -0600 + + test: Choose a random port for protocol tests + + test/functions.in | 3 +-- + test/tests/protocols | 18 ++++++++++-------- + test/tests/send | 1 - + 3 files changed, 11 insertions(+), 11 deletions(-) + +commit 0f358ebb11684e5a6c3ae55c89a2e3f43bc2bf4b +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 10:11:03 2016 -0600 + + inject: Add support for setting a null sender with -f + + NEWS | 3 ++- + src/inject.cc | 6 ++++-- + test/tests/inject/sender | 14 +++++++++++++- + 3 files changed, 19 insertions(+), 4 deletions(-) + +commit e390910b70099586f7e2c4540feae0d44682807a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 10:26:11 2016 -0600 + + test: Ignore all dotfiles in tests, not just .*.swp from vim + + test/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 65a86687c2314b3164a8648dd98eca79b44061e0 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 10:08:04 2016 -0600 + + Add note about -queue accepting the null sender + + NEWS | 2 ++ + 1 file changed, 2 insertions(+) + +commit 5f275304189782b1bd48b0c62f3e96f2cd18d979 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 09:51:40 2016 -0600 + + inject: Add a use_header_sender flag + + This removes the dependency on sender being empty when it is not set. + + src/inject.cc | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +commit 10de6736ac67d86c16cf9fe7abdc22515c7cbfd5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 09:34:19 2016 -0600 + + doc: Some fixes to the -inject man page + + doc/nullmailer-inject.1 | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +commit fcc790e023c44c9775c8532a11dde5fb39802165 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 07:15:01 2016 -0600 + + test: Make sure -smtpd accepts empty sender + + test/tests/smtpd | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 716df3be126923cfefbc9086a08183e6543cf055 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 13 21:06:02 2016 -0600 + + test: Normalize the smtp/qmqp accept success tests + + test/accept-qmqp.sh | 1 + + test/accept-smtp.sh | 7 +++++++ + test/tests/protocols | 39 ++++++++++++++------------------------- + 3 files changed, 22 insertions(+), 25 deletions(-) + create mode 100644 test/accept-qmqp.sh + create mode 100644 test/accept-smtp.sh + +commit 04c248a52bd00c7ceb044e62f35424c2e182f4c4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 13 21:05:21 2016 -0600 + + test: Add srcdir to runtests script + + test/Makefile.am | 2 +- + test/functions.in | 1 + + test/runtests.in | 5 +++-- + 3 files changed, 5 insertions(+), 3 deletions(-) + +commit 6c4434b5e1835c529c72243287df282dcf9650de +Merge: 894fcc1 aaf2026 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jan 14 07:20:08 2016 -0600 + + Merge branch 'ipv6' + +commit 894fcc11df471356d7ddff6bca7e2b4397c3e314 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 13 20:00:03 2016 -0600 + + Update the configure system for newer autoconf/automake + + .gitignore | 1 + + configure.in => configure.ac | 4 ++-- + lib/cli++/Makefile.am | 2 +- + lib/fdbuf/Makefile.am | 2 +- + lib/mystring/Makefile.am | 2 +- + protocols/Makefile.am | 2 +- + src/Makefile.am | 2 +- + test/Makefile.am | 6 +++--- + 8 files changed, 11 insertions(+), 10 deletions(-) + rename configure.in => configure.ac (97%) + +commit aaf202655000d98ba15379cbd33f78527c5a5c36 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 13 20:48:02 2016 -0600 + + lib: Add support for IPv6 for outgoing connections + + NEWS | 2 ++ + lib/tcpconnect.cc | 75 +++++++++++++++++++++++++++++++++++++++++----------- + test/tests/protocols | 8 +++++- + 3 files changed, 69 insertions(+), 16 deletions(-) + +commit 2c0812b0c2045a8f0aed0b3318d0ff5c9930dcb5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 13 20:10:50 2016 -0600 + + Add test for getaddrinfo to configure + + configure.in | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +commit 5206846d7fe19537ebceff61d300622d06a78fa3 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 13 17:34:37 2016 -0600 + + queue: Accept empty envelope sender address + + src/queue.cc | 4 ++-- + test/tests/queue/validate | 1 + + 2 files changed, 3 insertions(+), 2 deletions(-) + +commit 3278522a7f271dbabe813925b6582a341d6dbf2d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 13 17:33:15 2016 -0600 + + queue: Fix an envelope validation check and add tests + + src/queue.cc | 2 +- + test/functions.in | 24 ++++++++++++++++++--- + test/tests/queue/validate | 55 +++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 77 insertions(+), 4 deletions(-) + create mode 100755 test/tests/queue/validate + +commit 6c0ce505a7618caa5c493741c53c1f2591749358 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 13 09:31:06 2016 -0600 + + protocols: Fix gnutls integer pointer size mismatch warning + + NEWS | 2 ++ + protocols/tls_gnutls.cc | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +commit 9284992b5eabeb420b98ce6717aba1136710b859 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 17:11:31 2016 -0600 + + doc: Some fixes for the sendmail man page + + doc/sendmail.1 | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +commit 4a6e47edbae0bafe7bb9ad578e119031fe4d0210 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 17:00:10 2016 -0600 + + Fix typo: seperate => separate + + NEWS | 2 +- + TODO | 4 ++-- + doc/nullmailer-inject.1 | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +commit 3d73290d5745eb97687ae8ff4440f5c660b6f99b +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 16:56:47 2016 -0600 + + doc: Add missing control files to nullmailer.7 + + doc/nullmailer.7 | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 397a1d3332a0631ccf6a2743786592dc5297a464 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 16:47:39 2016 -0600 + + inject: Report errors on stderr, not stdout + + NEWS | 2 ++ + src/inject.cc | 14 +++++++------- + 2 files changed, 9 insertions(+), 7 deletions(-) + +commit d158280e4b79a97e7e292c19af1430ac3d61e3cb +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 16:37:18 2016 -0600 + + Add systemd nullmailer service file + + scripts/nullmailer.service | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + create mode 100644 scripts/nullmailer.service + +commit ce2b78cf827905124fba6de4d4efbb097cf2b717 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 15:45:40 2016 -0600 + + protocols: Fix handling of options passed from -send + + protocols/protocol.cc | 7 +++++-- + test/functions.in | 17 ++++++++++++++++- + test/tests/protocols | 36 +++++++++++++++++++++++++++++------- + 3 files changed, 50 insertions(+), 10 deletions(-) + +commit 856ed189ebd5179924c442f131aa45cdfacb83a8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 15:25:58 2016 -0600 + + lib/cli++: Move call to build_options into main out of cli_parse_args + + lib/cli++/main.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 5188f0b560ab192f18b01f420164202d384b5ffd +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 09:45:46 2016 -0600 + + test: Make sure -send sets host in dummy protocol + + test/tests/send | 2 ++ + 1 file changed, 2 insertions(+) + +commit eeb0fba50b92564ada32f03858237c507d61ea57 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 09:45:12 2016 -0600 + + test: Move temporary directory to test/tmp + + This moves the temporary test directory out of /tmp and into test/tmp, + and verifies that the sources were configured with the proper prefix + path. + + .gitignore | 3 +++ + test/Makefile.am | 2 +- + test/{functions => functions.in} | 3 ++- + test/runtests.in | 16 ++++++++++++++-- + test/tests/queue/rewrite | 12 ++++++------ + 5 files changed, 26 insertions(+), 10 deletions(-) + rename test/{functions => functions.in} (96%) + +commit f9d326fcc74ab941e232b7aebe784f89ccad54d5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 09:28:48 2016 -0600 + + test: Move running tests into a script + + This makes it a little simpler to run the individual tests by hand. + + .gitignore | 3 +++ + test/Makefile.am | 17 ++++++++--------- + test/runtests.in | 14 ++++++++++++++ + 3 files changed, 25 insertions(+), 9 deletions(-) + create mode 100644 test/runtests.in + +commit 9663b43742381466855d64112b254a1d095b7a34 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 12 10:26:03 2016 -0600 + + lib/defines: Turn defines into real constant strings, not just pointers + + lib/defines.h | 16 ++++++++-------- + lib/make_defines.sh | 18 ++++++++++-------- + 2 files changed, 18 insertions(+), 16 deletions(-) + +commit cb6098a4f111abf86b34337b8a28333c370e443a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu May 21 11:50:17 2015 -0600 + + protocols: Log success/failure to stdout instead of stderr + + protocols/protocol.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit be8a42054b7ce0f39fd2d077ca62b9e899762a15 +Merge: a5b4dd2 a8420e9 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue May 26 17:27:03 2015 -0600 + + Merge pull request #16 from abh/patch-1 + + Update spec file to use Requires(pre,preun) + +commit a5b4dd2d1d3291ddd5dda7b422a987795cc58606 +Author: Michael T. Babcock <mike@triplepc.ca> +Date: Thu May 21 11:06:04 2015 -0600 + + protocols: Add support for older versions of gnutls + + I have had a problem compiling nullmailer 1.13 with gnutls 1.4.1 (CentOS + 5), so I added the following patch to make it work: + + protocols/tls_gnutls.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +commit ed80ca125fbf418f6437fd166b921907cd3a70bf +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu May 21 11:01:01 2015 -0600 + + protocols: Add option to set a separate TLS client cert private key file + + NEWS | 2 ++ + doc/nullmailer-send.8 | 5 +++++ + protocols/protocol.cc | 2 ++ + protocols/protocol.h | 1 + + protocols/tls_gnutls.cc | 5 ++++- + 5 files changed, 14 insertions(+), 1 deletion(-) + +commit ee3082c960c0de4764b4bfef688bac97a6346a9a +Merge: 70b4498 5e9316c +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu May 21 10:38:46 2015 -0600 + + Merge pull request #25 from blueness/musl + + lib/fdbuf/fdbuf.h: include <unistd.h> + +commit 70b449872633ff288189ea0cc41f00b082c97b5a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu May 21 09:09:35 2015 -0600 + + protocols: Rename ssl options to tls + + doc/nullmailer-send.8 | 10 ++++++++-- + protocols/protocol.cc | 14 ++++++++------ + protocols/protocol.h | 4 ++-- + protocols/qmqp.cc | 2 +- + protocols/smtp.cc | 2 +- + 5 files changed, 20 insertions(+), 12 deletions(-) + +commit 1978cd40a5dde7359075c63c68b6e1f294c92c34 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed May 20 20:57:43 2015 -0600 + + send: Document the protocol options in the man page + + doc/nullmailer-send.8 | 70 +++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 48 insertions(+), 22 deletions(-) + +commit 3d2aa642dc7215b36afa494ff2e3631617781df5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed May 20 20:43:59 2015 -0600 + + send: Note that the leading "--" before protocol options is optional + + doc/nullmailer-send.8 | 3 +++ + 1 file changed, 3 insertions(+) + +commit 74aeb537149c92eb4b8ba8173fc2d60eec086038 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed May 20 20:28:08 2015 -0600 + + send: Add support for quoted options to the "remotes" file + + NEWS | 2 ++ + doc/nullmailer-send.8 | 3 ++- + src/send.cc | 25 +++---------------------- + 3 files changed, 7 insertions(+), 23 deletions(-) + +commit a5e04f340d62962f378b27a3bccc85bc0050389e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed May 20 20:04:20 2015 -0600 + + lib/argparse: Add sh-like argument parsing, for use in remotes file + + .gitignore | 1 + + lib/Makefile.am | 1 + + lib/argparse.cc | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ + lib/argparse.h | 10 +++++++++ + test/Makefile.am | 8 +++++-- + test/argparse-test.cc | 49 +++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 127 insertions(+), 2 deletions(-) + create mode 100644 lib/argparse.cc + create mode 100644 lib/argparse.h + create mode 100644 test/argparse-test.cc + +commit 29734e270ab05f9493c4c8bce189ccda1e5669a5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun May 17 17:11:14 2015 -0600 + + Add NEWS note about command line handling change + + NEWS | 2 ++ + 1 file changed, 2 insertions(+) + +commit 4f6672db2117920e2ec1b53cbeb837d5857bb169 +Merge: da55b71 b181a6d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun May 17 17:09:58 2015 -0600 + + Merge branch 'pipe-options' + +commit b181a6d6ea363b52d8fa35949f61719300e3d9ca +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Apr 19 11:21:53 2013 -0600 + + send: Send all options to protocol modules on a pipe on FD 0, and message on FD 3 + + src/send.cc | 36 +++++++++++++++++++++++++----------- + 1 file changed, 25 insertions(+), 11 deletions(-) + +commit 3588792105373e243cef3462aa2e0797f43a0a8b +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Apr 19 11:09:07 2013 -0600 + + send: Turn options list into string (dummy commit) + + src/send.cc | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +commit c540d9ee8961e216da58583891ca8738176e827c +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Apr 19 11:04:27 2013 -0600 + + protocols: Handle configuration options on stdin, message on FD 3 + + Options are read in one per line, terminated by an empty line. Format is + name=value + where "name" is one of the long cli options (see --help output). + + protocols/protocol.cc | 41 ++++++++++++++++++++++++++++++++++------- + test/functions | 3 ++- + test/tests/protocols | 14 +++++++------- + test/tests/send | 5 ++--- + 4 files changed, 45 insertions(+), 18 deletions(-) + +commit 304992617a4f27be6e501244c3d91ae1aba13c5a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Apr 21 16:25:47 2013 -0600 + + lib/cli++: Expose command-line parsing function + + lib/cli++/cli++.h | 1 + + lib/cli++/main.cc | 6 +++--- + 2 files changed, 4 insertions(+), 3 deletions(-) + +commit 5e9316c669e752fcd9058b28952919bccd967640 +Author: Anthony G. Basile <blueness@gentoo.org> +Date: Sat Jan 31 23:55:48 2015 +0000 + + lib/fdbuf/fdbuf.h: include <unistd.h> + + class fdobuf in lib/fdbuf/fdobuf.h makes use of uid_t and gid_t, + but these are defined in <unistd.h> according to POSIX. With libc's + that adhere strictly to standards, like musl, this breaks the build. + + We add <unistd.h> to fdbuf.h which is included by fdbuf.h. + + Signed-off-by: Anthony G. Basile <blueness@gentoo.org> + + lib/fdbuf/fdbuf.h | 1 + + 1 file changed, 1 insertion(+) + +commit a8420e922854f01cd35c74d2a362d5197f4f5000 +Author: Ask Bjørn Hansen <ask@develooper.com> +Date: Sun Mar 2 15:20:08 2014 -0800 + + Update spec file to use Requires(pre,preun) + + PreReq appears to be deprecated since some old version of RPM in favor of "Requires(pre,preun)". + + spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit da55b71b6136bcefc7aa784a7f9fd45987670a7a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Sep 13 13:56:24 2013 -0600 + + queue: Add an "allmailfrom" control file, to force a fixed sender + + NEWS | 3 +++ + doc/nullmailer-queue.8 | 4 ++++ + src/queue.cc | 4 ++++ + test/tests/queue/rewrite | 26 ++++++++++++++++++++++++++ + 4 files changed, 37 insertions(+) + +commit 43601e41dd9160c09751a15fd7fcbe6003a61755 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Sep 13 13:54:22 2013 -0600 + + Drop extraneous -q in tests/queue/rewrite + + test/tests/queue/rewrite | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit f2c74f27ad9ea1786efc7c66a831dd6eb8d60cc5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Sep 13 13:30:21 2013 -0600 + + Add news note for error handling changes + + NEWS | 2 ++ + 1 file changed, 2 insertions(+) + +commit c3a800acde4aab80e05a4ca31f1ff0912640368c +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Sep 13 13:29:26 2013 -0600 + + Bump version to 1.14 + + NEWS | 5 +++++ + README | 2 +- + configure.in | 2 +- + 3 files changed, 7 insertions(+), 2 deletions(-) + +commit d799dc705629b91de4d54959e7e9621d99a76dc4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Sep 13 13:23:02 2013 -0600 + + queue: Drop the remapadmin boolean + + It is completely unneeded, since adminaddr will always be non-empty when + it would be true. + + src/queue.cc | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +commit 3f93a80fc2ff3fa99e7149c8d56d70db8c638233 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Sep 4 13:06:45 2013 -0600 + + queue: Rename parameter to validate_addr to avoid confusion + + src/queue.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 24f33039863c99e3d466a723b0b21fa2e808b4fa +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 27 16:26:43 2013 -0600 + + nullmailer-send: Reword multiple remote documentation to match actual behavior + + doc/nullmailer-send.8 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3cde27af63d6509aaf52c45bc1595f90a4574680 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 18 11:48:54 2013 -0600 + + send: Reorganize exec_remote to be a member of struct remote + + src/send.cc | 35 +++++++++++++++++++---------------- + 1 file changed, 19 insertions(+), 16 deletions(-) + +commit 1d4d8405b3b3011061f35369eaec9bee2fa004e0 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 18 11:35:03 2013 -0600 + + send: Improve error messages when reading config files + + src/send.cc | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +commit 9de2e74f64f7daf017ebf4c5220c797b380994b2 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 18 07:53:27 2013 -0600 + + Make system errors on reading config files fatal (with useful message) + + lib/Makefile.am | 2 +- + lib/config_read.cc | 2 ++ + lib/config_readlist.cc | 2 +- + protocols/tls_none.cc => lib/config_syserr.cc | 21 +++++++++------------ + lib/configio.h | 1 + + src/Makefile.am | 6 +++--- + src/queue.cc | 2 ++ + src/send.cc | 2 ++ + 8 files changed, 21 insertions(+), 17 deletions(-) + copy protocols/tls_none.cc => lib/config_syserr.cc (74%) + +commit 4aff5a4e9251a0f189015b90f02c6e8edd3c3ffc +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Apr 17 17:36:49 2013 -0600 + + lib/cli++: Add helper function for outputting fatal system errors + + lib/cli++/cli++.h | 6 ++++++ + lib/cli++/messages.cc | 54 +++++++++++++++++++++++++++++++++++++-------------- + 2 files changed, 45 insertions(+), 15 deletions(-) + +commit 437bb66c9c468c9bc8cc5e21bdcd6c6a28291b75 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Apr 17 17:36:31 2013 -0600 + + Add ERR_CONFIG error code for problems reading config files + + lib/errcodes.cc | 1 + + lib/errcodes.h | 1 + + 2 files changed, 2 insertions(+) + +commit 048f87ccd1f6e3c86a3b27b6ed69ddb1201ec669 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 15 08:47:46 2013 -0600 + + Stamp version 1.13 + + NEWS | 4 ++++ + README | 7 +++++-- + configure.in | 2 +- + 3 files changed, 10 insertions(+), 3 deletions(-) + +commit af1bd422d127ea968d708952ff49a6c3bb0f44a5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 15 08:46:52 2013 -0600 + + sendmail: Document the -b[mps] mode options in the man page + + doc/sendmail.1 | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +commit 4d89f70c1e2e414444d1e5087685e3deec3d2f0f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Apr 12 10:46:22 2013 -0600 + + smtpd: Fix growing recipient list when sending multiple messages + + If the client program sends multiple messages without issuing the RSET + command, the recipient list would not get cleared. As a result, the + second message would have its recipient list added to that of the first, + and so on. This change simply resets the list internally. + + NEWS | 4 ++++ + src/smtpd.cc | 1 + + test/tests/smtpd | 6 ++++++ + 3 files changed, 11 insertions(+) + +commit 2de136d139e7a37a06300f75b99aaee3efcd600a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 4 16:09:19 2013 -0600 + + Stamped release with today's date + + NEWS | 3 +++ + README | 6 +++--- + 2 files changed, 6 insertions(+), 3 deletions(-) + +commit 5dad4cb8e17f645e5fa048cb82c16247f9d9ad6b +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 27 15:18:43 2013 -0600 + + inject: Fix handling of messages with no body + + If there is no blank line following the header (and hence no body), the + last line of the header may be duplicated in the body of the message. + This fixes that boundary condition. + + NEWS | 2 ++ + src/inject.cc | 5 ++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +commit ca494e2135ef81d8e3580039c3445d7a15409532 +Merge: eaa532e c94c8bd +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 27 14:48:42 2013 -0600 + + Merge branch 'backoff' + +commit c94c8bd4ae8f270d0e213365933d84cf0d0b5734 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Mar 14 10:26:03 2013 -0600 + + send: Fix up pause time back off calculation + + src/send.cc | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +commit eaa532ebff1b01230384c0229f7b53687dfc99f6 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 27 09:01:52 2013 -0600 + + smtpd: Strip leading periods from data as required + + Bug reported by Sebastian Nickel + + NEWS | 2 ++ + src/smtpd.cc | 2 ++ + test/tests/smtpd | 8 ++++++-- + 3 files changed, 10 insertions(+), 2 deletions(-) + +commit 518cc1b89742f33a68128c043c5575e79e8d46dd +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Feb 22 16:25:13 2013 -0600 + + send: Back off rescan times when sending fails. + + NEWS | 2 ++ + doc/nullmailer-send.8 | 13 +++++++++++-- + src/send.cc | 25 +++++++++++++++++++------ + 3 files changed, 32 insertions(+), 8 deletions(-) + +commit 8563947d787b918c71f69e0b4f43275619cd3852 +Merge: a3fb6bd 8b2bdff +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Mar 19 13:50:00 2013 -0700 + + Merge pull request #9 from tpo/master + + documentation: manual delivery trigger, transport module options + +commit 8b2bdff730a475e276c9b5a637e19f9402850bb9 +Author: Tomas Pospisek <tpo_hp@sourcepole.ch> +Date: Fri Mar 15 10:09:47 2013 +0100 + + list smpt and qmqp --help in 'see also' section + + doc/nullmailer-send.8 | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 4e821abe4a8d473e4acba41d8495a1c8a44deb16 +Author: Tomas Pospisek <tpo_hp@sourcepole.ch> +Date: Fri Mar 15 10:08:59 2013 +0100 + + document how to find out about protocol modules' options + + doc/nullmailer-send.8 | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +commit a79fc602b4bdb1ff80e6f3a56d49bfbf20e7b750 +Author: Tomas Pospisek <tpo_hp@sourcepole.ch> +Date: Fri Mar 15 10:06:08 2013 +0100 + + document how to start delivery manually + + doc/nullmailer-send.8 | 5 +++++ + 1 file changed, 5 insertions(+) + +commit a3fb6bd48cfca9587c21d6e6e835ce3cc2326960 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Mar 14 10:12:42 2013 -0600 + + nullmailer-queue: Support multiple admin addresses + + NEWS | 2 ++ + doc/nullmailer-queue.8 | 3 ++- + src/queue.cc | 1 + + test/tests/queue/rewrite | 14 +++++++++++++- + 4 files changed, 18 insertions(+), 2 deletions(-) + +commit 2d6d0dc09daa48abbfece9fc4d7674dd9095684b +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Dec 19 21:25:26 2012 -0600 + + protocols/smtp: Send QUIT on success too + + Apparently some SMTP receivers will warn about senders that didn't send + QUIT. Don't know why, and this should help shut them up. + + NEWS | 1 + + protocols/smtp.cc | 2 ++ + 2 files changed, 3 insertions(+) + +commit c0159f5fdf523f4dc508bc85e75c9e73663066b8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Dec 19 21:24:40 2012 -0600 + + Bump version to 1.12 + + NEWS | 3 +++ + configure.in | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +commit ef77697eafa9033063fe9e3c546f2f1e451da005 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 14 09:44:38 2012 -0600 + + Tagged the README with today's date + + README | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit d5a7ce0be1d08d3a3636af471241346e219306a4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jun 12 14:52:50 2012 -0600 + + protocols: Add support for client certificate files. + + NEWS | 2 ++ + protocols/protocol.cc | 2 ++ + protocols/protocol.h | 1 + + protocols/tls_gnutls.cc | 4 ++++ + 4 files changed, 9 insertions(+) + +commit 16674b30624c3240aad4b4ad1b9e85e6c08f7e8e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jun 12 14:47:15 2012 -0600 + + sendmail: Ignore all sendmail options + + NEWS | 2 +- + src/sendmail.cc | 21 +-------------------- + 2 files changed, 2 insertions(+), 21 deletions(-) + +commit 2704d1305f3d7c474520b3c5cb0063d36b180698 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jun 12 14:21:44 2012 -0600 + + lib/cli++: Fix handling of single-char options with values + + Invoking 'sendmail -FNAME' fails without this patch. + + This change also introduces a set of self-tests. + + NEWS | 2 ++ + lib/cli++/main.cc | 29 ++++++++++++-------- + test/Makefile.am | 13 +++++++-- + test/clitest.cc | 45 +++++++++++++++++++++++++++++++ + test/clitest.sh | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 157 insertions(+), 13 deletions(-) + create mode 100644 test/clitest.cc + create mode 100644 test/clitest.sh + +commit dd9bb3ece55d2ce2b940b67e069d4ce800f54b5e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jun 12 08:31:13 2012 -0600 + + sendmail: Add -odd -odi and -odq options for compatibility + + NEWS | 2 ++ + src/sendmail.cc | 6 ++++++ + 2 files changed, 8 insertions(+) + +commit f6f6a935463211a4e2fccb12448824bf82fd2362 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jun 12 08:30:43 2012 -0600 + + Bump version to 1.11 + + NEWS | 5 +++++ + configure.in | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +commit e6bc62f9ba314c024c8cb96574b9e9897d1624c2 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu May 24 15:49:00 2012 -0600 + + protocols: Remove unneeded (?) gnutls/abstract.h include + + protocols/tls_gnutls.cc | 3 --- + 1 file changed, 3 deletions(-) + +commit 221121d4d568e6e3922654641645dbace6f1cc43 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Apr 24 09:41:44 2012 -0600 + + test: Sleep a little longer in the send test to prevent a race + + test/tests/send | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b34be1b1b7f3c9b1f5755251e62833b7ce4ece4f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Apr 24 08:55:52 2012 -0600 + + makedist.in: Stop building RPMs + + makedist.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 56a60e2fd00370ef3ad04959144aed23dd35d43d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Apr 24 08:55:27 2012 -0600 + + spec: Updates for tls and nullmailer-smtpd + + spec | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 5e32780d7c9c57acb5c18c255d95271deb40e885 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Apr 24 07:49:21 2012 -0600 + + README: Stamp with today's date + + README | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 871c21f821416ddcb93e4e1bc87ec82bdd8aba12 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 23 13:44:33 2012 -0600 + + test: Fix typo in find command + + test/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c24509e9b0cd8fe4430bdd3daa0bcf733ea1eb6d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 23 11:01:58 2012 -0600 + + src/smtpd: Add missing #include + + src/smtpd.cc | 1 + + 1 file changed, 1 insertion(+) + +commit fb6326ff2e5eb767e53f7f1e30748bcf489d26df +Merge: d0cc453 75f4a52 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 23 10:59:54 2012 -0600 + + Merge branch 'lsb' + + Conflicts: + NEWS + src/sendmail.cc + +commit d0cc4538313204a434982a42aa1182fca5c032e2 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 23 10:28:07 2012 -0600 + + src/sendmail: Eliminate a few compiler warnings + + src/sendmail.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 81f0d6fdf65401a6fbd63b83e1a711812906b6f5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 23 10:09:19 2012 -0600 + + protocols/tls: Added support for gnutls prior to version 2.10 + + gnutls-2.10 introduced the gnutls_certificate_set_verify_function, which + allows for verifying server certificates as soon as they're sent instead + of after the handshake is complete. This adds a workaround for the + function not being present in older versions by calling the cert + verification after the handshake. + + configure.in | 7 ++++++- + protocols/tls_gnutls.cc | 12 ++++++++++-- + 2 files changed, 16 insertions(+), 3 deletions(-) + +commit b635aef827d8455e9a0eb02a6f9e93fbf250bbcd +Merge: 9e94d29 dd57bf9 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 19 17:10:16 2012 -0600 + + Merge branch 'tls' + +commit 9e94d298adc142b0ff68044869f20d2450429b63 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 19 17:06:45 2012 -0600 + + Fix a few warnings in autoconf files + + acinclude.m4 | 8 ++++---- + configure.in | 1 + + 2 files changed, 5 insertions(+), 4 deletions(-) + +commit dd57bf991c9aa1e9ee8721c8c64b2021162c1f1a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 19 16:32:06 2012 -0600 + + protocols: Add support for server certificate verification + + TODO | 3 --- + protocols/protocol.cc | 8 ++++++++ + protocols/protocol.h | 7 +++++++ + protocols/tls_gnutls.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 61 insertions(+), 3 deletions(-) + +commit eb902c3a5808718f59d0009565900104bca55f04 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Apr 17 16:07:02 2012 -0600 + + protocols: Add support for STARTTLS + + NEWS | 2 +- + TODO | 1 - + protocols/protocol.cc | 12 ++++++++++-- + protocols/protocol.h | 2 ++ + protocols/qmqp.cc | 7 +++++++ + protocols/smtp.cc | 14 +++++++++++++- + 6 files changed, 33 insertions(+), 5 deletions(-) + +commit 436afd26338d319cec9f854bb524c740a1639656 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Apr 17 15:33:32 2012 -0600 + + protocols: Make SSL/TLS support optional in configure + + INSTALL | 3 +++ + TODO | 1 - + configure.in | 9 +++++++++ + lib/fdbuf/Makefile.am | 11 +++++++---- + protocols/Makefile.am | 16 ++++++++++++---- + protocols/protocol.cc | 6 ++---- + protocols/{tls.cc => tls_gnutls.cc} | 0 + lib/config_readint.cc => protocols/tls_none.cc | 24 ++++++++++++------------ + 8 files changed, 45 insertions(+), 25 deletions(-) + rename protocols/{tls.cc => tls_gnutls.cc} (100%) + copy lib/config_readint.cc => protocols/tls_none.cc (76%) + +commit 14568cc6fe479bfd3a5fab160d7f87e0e3abbe51 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Apr 17 15:11:13 2012 -0600 + + protocols: Move TLS code into separate source + + TODO | 1 - + protocols/Makefile.am | 4 +- + protocols/protocol.cc | 54 ++------------------------ + protocols/protocol.h | 3 ++ + protocols/{protocol.cc => tls.cc} | 81 ++++----------------------------------- + 5 files changed, 15 insertions(+), 128 deletions(-) + copy protocols/{protocol.cc => tls.cc} (53%) + +commit 450b50fb579dc0d0bc911029245b394e1088c7de +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Apr 17 14:36:34 2012 -0600 + + protocols: Add support for SSL connections using gnutls + + NEWS | 2 ++ + TODO | 8 +++--- + protocols/Makefile.am | 4 +-- + protocols/protocol.cc | 72 +++++++++++++++++++++++++++++++++++++++++++++++---- + 4 files changed, 76 insertions(+), 10 deletions(-) + +commit 1d31cee72dc3af76590f07156d55c6b2733a5d04 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 16 15:14:57 2012 -0600 + + protocols: Add --ssl option (unimplemented) + + protocols/protocol.cc | 7 +++++-- + protocols/protocol.h | 2 ++ + protocols/qmqp.cc | 1 + + protocols/smtp.cc | 1 + + 4 files changed, 9 insertions(+), 2 deletions(-) + +commit e938f48e637584d4e7198a45a5849fcf0f7d03b1 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 16 15:00:47 2012 -0600 + + lib/fdbuf: Add TLS ibuf and obuf classes, using gnutls + + lib/fdbuf/Makefile.am | 4 ++++ + lib/fdbuf/{fdbuf_copy.cc => tlsibuf.cc} | 29 +++++++++++----------------- + lib/fdbuf/{fdobuf_chownmod.cc => tlsibuf.h} | 30 ++++++++++++++--------------- + lib/fdbuf/{fdbuf_copy.cc => tlsobuf.cc} | 29 +++++++++++----------------- + lib/fdbuf/{fdobuf_chownmod.cc => tlsobuf.h} | 30 ++++++++++++++--------------- + 5 files changed, 54 insertions(+), 68 deletions(-) + copy lib/fdbuf/{fdbuf_copy.cc => tlsibuf.cc} (63%) + copy lib/fdbuf/{fdobuf_chownmod.cc => tlsibuf.h} (65%) + copy lib/fdbuf/{fdbuf_copy.cc => tlsobuf.cc} (63%) + copy lib/fdbuf/{fdobuf_chownmod.cc => tlsobuf.h} (65%) + +commit e275797c5ab06f1cd1683f735127605352b477ee +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 16 13:01:41 2012 -0600 + + lib/fdbuf: Fix header include issues + + lib/fdbuf/fdbuf.h | 4 ++-- + lib/fdbuf/fdibuf.h | 2 ++ + lib/fdbuf/fdobuf.h | 2 +- + 3 files changed, 5 insertions(+), 3 deletions(-) + +commit 4ee43718cd83a25562c853e24ebe45ce3141d62d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 16 12:39:53 2012 -0600 + + lib/fdbuf: Implement virtual read/write functions for better extending + + lib/fdbuf/fdibuf.cc | 13 +++++++++---- + lib/fdbuf/fdibuf.h | 1 + + lib/fdbuf/fdobuf.cc | 13 +++++++++---- + lib/fdbuf/fdobuf.h | 1 + + 4 files changed, 20 insertions(+), 8 deletions(-) + +commit 3539a0e83a2307b2d60b1c10cbd50c5930b6719e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 16 15:28:48 2012 -0600 + + protocols: Allocate I/O fdbuf objects in protocol wrapper + + protocols/protocol.cc | 6 +++++- + protocols/protocol.h | 2 +- + protocols/qmqp.cc | 14 +++++++------- + protocols/smtp.cc | 14 +++++++------- + 4 files changed, 20 insertions(+), 16 deletions(-) + +commit 245971bc0f9856ee98f6505d952a91c59546c3aa +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 16 15:21:28 2012 -0600 + + protocols: Use reference instead of pointer in protocol_* calling convention + + protocols/protocol.cc | 4 ++-- + protocols/protocol.h | 4 ++-- + protocols/qmqp.cc | 32 ++++++++++++++++---------------- + protocols/smtp.cc | 22 +++++++++++----------- + 4 files changed, 31 insertions(+), 31 deletions(-) + +commit 3c23536837b00123f3fa8671c2c7e37322212cda +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 16 15:11:39 2012 -0600 + + protocols: Handle default port numbers in the wrapper code + + protocols/protocol.cc | 5 +++++ + protocols/protocol.h | 3 +-- + protocols/qmqp.cc | 2 +- + protocols/smtp.cc | 2 +- + 4 files changed, 8 insertions(+), 4 deletions(-) + +commit f16c5b15f468c18d3867fbf33cae17bb4b1ca288 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Apr 15 13:21:05 2012 -0600 + + protocols/smtp: Add autodetection of authentication mode + + NEWS | 2 ++ + protocols/protocol.cc | 4 ++-- + protocols/protocol.h | 3 ++- + protocols/smtp.cc | 62 ++++++++++++++++++++++++++++++++++++++++++++++----- + 4 files changed, 62 insertions(+), 9 deletions(-) + +commit acd189b0c581b73ea5ffaa4b4cb8ba5c5bf2d242 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Apr 15 13:12:03 2012 -0600 + + protocols/smtp: Move auth code into smtp class + + protocols/smtp.cc | 46 ++++++++++++++++++++++++++++------------------ + 1 file changed, 28 insertions(+), 18 deletions(-) + +commit 53e7cfcaa4916023d047187abfb4d9ed8adcfd08 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Apr 15 12:33:51 2012 -0600 + + protocol/smtp: Provide interface for recording command responses + + protocols/smtp.cc | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +commit 75f4a52ba1fa1916a5c64cf279ef883ecb24c142 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 14 10:18:16 2012 -0600 + + Add tests for nullmailer-smtpd + + test/functions | 1 + + test/tests/smtpd | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 72 insertions(+) + create mode 100644 test/tests/smtpd + +commit c8559d15c070c1846fe37306a9611c9dd02510cc +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 14 10:04:14 2012 -0600 + + nullmailer-smtpd: Make sure commands that require a parameter have one + + src/smtpd.cc | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +commit 9c8e3bd1155113cfef6a0fc215e128baf37ea7ff +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 14 09:56:48 2012 -0600 + + test: Drop the grep against .svn since it's not used any more + + test/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 5b85b41aa188e38dfb984d744b19cb6713b75fea +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 14 09:04:30 2012 -0600 + + sendmail: Add support for -bs (SMTP) mode + + NEWS | 2 +- + src/sendmail.cc | 3 +-- + 2 files changed, 2 insertions(+), 3 deletions(-) + +commit 7970d43393021a5b7603f94f11aab0152af4f325 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 14 09:01:17 2012 -0600 + + nullmailer-smtpd: Add simple SMTP agent, for sendmail -bs mode + + .gitignore | 1 + + src/Makefile.am | 6 +- + src/smtpd.cc | 295 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 301 insertions(+), 1 deletion(-) + create mode 100644 src/smtpd.cc + +commit f0b2f36a1f8c8dbc11f6392964b5570d90d1d26c +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Mar 14 09:00:35 2012 -0600 + + mystring: Fix (previously unused) implementation of mystring::upper + + lib/mystring/upper.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit cb1a4b414d0f80e2066d7daf35b7eba622be693e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Mar 12 16:02:10 2012 -0600 + + sendmail: Add support for -bp (mailq) mode + + NEWS | 2 ++ + src/sendmail.cc | 51 +++++++++++++++++++++++++-------------------------- + 2 files changed, 27 insertions(+), 26 deletions(-) + +commit df9818e90dc9130291916a1d96fc4789f768a603 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Mar 12 15:49:05 2012 -0600 + + lib/cli++: Fix handling of error messages from short options + + lib/cli++/cli++.h | 4 ++-- + lib/cli++/main.cc | 28 ++++++++++++++++++---------- + 2 files changed, 20 insertions(+), 12 deletions(-) + +commit e301f0e28a97424d9b163959a43b251137731ca3 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Mar 12 15:34:42 2012 -0600 + + sendmail: Break out options using hew cli_only_long mode + + src/sendmail.cc | 79 ++++++++++++++++++++++++++++++++++++++------------------- + 1 file changed, 53 insertions(+), 26 deletions(-) + +commit 0a7dab3bc20691e450c2cd61d927c74723003cc3 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Mar 12 15:21:49 2012 -0600 + + lib/cli++: Complete implementation of cli_only_long option + + This change adds support on the command line for "-long" options + alongside "--long" options if cli_only_long is set. + + lib/cli++/main.cc | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +commit 7a30893489004e4c462164e6ae2dc984ea189056 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Feb 29 22:27:01 2012 -0600 + + lib/cli++: Add start of cli_only_long option + + A new boolean, cli_only_long implements a new mode of operation, where + both long and short options can be prefixed with a single "-". + + This change only implements the help text output. + + lib/cli++/Makefile.am | 2 +- + lib/cli++/cli++.h | 3 +++ + lib/cli++/main.cc | 67 +++++++++++++++++++++++++++----------------------- + lib/cli++/only_long.cc | 3 +++ + 4 files changed, 43 insertions(+), 32 deletions(-) + create mode 100644 lib/cli++/only_long.cc + +commit 16a1e560761de3a1deba807adc758e4e1dd07be3 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Mar 12 16:03:26 2012 -0600 + + Bump version to 1.10 + + NEWS | 5 +++++ + README | 2 +- + configure.in | 2 +- + 3 files changed, 7 insertions(+), 2 deletions(-) + +commit b445376bbb00d64a6e4a54f426658027832a0ce8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Feb 29 21:00:10 2012 -0600 + + lib/fdbuf: Initial commit from current sources + + lib/fdbuf/Makefile.am | 22 +++ + lib/fdbuf/fdbuf.cc | 107 +++++++++++ + lib/fdbuf/fdbuf.h | 82 ++++++++ + lib/{mystring/count.cc => fdbuf/fdbuf_copy.cc} | 25 ++- + lib/fdbuf/fdbuf_test.cc | 16 ++ + lib/fdbuf/fdibuf.cc | 192 +++++++++++++++++++ + lib/fdbuf/fdibuf.h | 50 +++++ + lib/{mystring/iter.cc => fdbuf/fdibuf_mystring.cc} | 54 +++--- + .../count.cc => fdbuf/fdibuf_netstring.cc} | 28 ++- + lib/fdbuf/fdobuf.cc | 209 +++++++++++++++++++++ + lib/fdbuf/fdobuf.h | 91 +++++++++ + .../count.cc => fdbuf/fdobuf_chownmod.cc} | 21 ++- + lib/{mystring/iter.cc => fdbuf/fdobuf_seek.cc} | 50 ++--- + lib/{mystring/count.cc => fdbuf/fdobuf_signed.cc} | 25 ++- + .../count.cc => fdbuf/fdobuf_unsigned.cc} | 21 ++- + 15 files changed, 913 insertions(+), 80 deletions(-) + create mode 100644 lib/fdbuf/Makefile.am + create mode 100644 lib/fdbuf/fdbuf.cc + create mode 100644 lib/fdbuf/fdbuf.h + copy lib/{mystring/count.cc => fdbuf/fdbuf_copy.cc} (56%) + create mode 100644 lib/fdbuf/fdbuf_test.cc + create mode 100644 lib/fdbuf/fdibuf.cc + create mode 100644 lib/fdbuf/fdibuf.h + copy lib/{mystring/iter.cc => fdbuf/fdibuf_mystring.cc} (53%) + copy lib/{mystring/count.cc => fdbuf/fdibuf_netstring.cc} (62%) + create mode 100644 lib/fdbuf/fdobuf.cc + create mode 100644 lib/fdbuf/fdobuf.h + copy lib/{mystring/count.cc => fdbuf/fdobuf_chownmod.cc} (72%) + copy lib/{mystring/iter.cc => fdbuf/fdobuf_seek.cc} (61%) + copy lib/{mystring/count.cc => fdbuf/fdobuf_signed.cc} (67%) + copy lib/{mystring/count.cc => fdbuf/fdobuf_unsigned.cc} (70%) + +commit 46fa7fa8eb1f1aa8f787e186db7f3d1208ea2451 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Feb 29 20:59:55 2012 -0600 + + lib/mystring: Initial commit from current sources + + lib/mystring/Makefile.am | 25 +++++ + lib/mystring/append.cc | 19 ++++ + lib/mystring/assign.cc | 55 ++++++++++ + lib/{config_readint.cc => mystring/count.cc} | 25 ++--- + lib/mystring/fdobuf.cc | 9 ++ + lib/mystring/find_first_ch.cc | 11 ++ + lib/mystring/find_first_of.cc | 22 ++++ + lib/mystring/find_last_ch.cc | 14 +++ + lib/mystring/find_last_of.cc | 24 ++++ + lib/{canonicalize.cc => mystring/iter.cc} | 46 +++++--- + lib/{config_readint.cc => mystring/iter.h} | 41 +++---- + lib/mystring/join.cc | 61 +++++++++++ + lib/mystring/join.h | 76 +++++++++++++ + lib/mystring/lower.cc | 19 ++++ + lib/mystring/lstrip.cc | 10 ++ + lib/mystring/mystring.cc | 28 +++++ + lib/mystring/mystring.h | 127 ++++++++++++++++++++++ + lib/mystring/operator_in.cc | 33 ++++++ + lib/mystring/rep.cc | 157 +++++++++++++++++++++++++++ + lib/{config_readint.cc => mystring/rep.h} | 47 +++++--- + lib/mystring/rstrip.cc | 10 ++ + lib/mystring/strip.cc | 13 +++ + lib/mystring/sub.cc | 37 +++++++ + lib/mystring/subst.cc | 18 +++ + lib/mystring/trace.h | 11 ++ + lib/mystring/upper.cc | 21 ++++ + 26 files changed, 886 insertions(+), 73 deletions(-) + create mode 100644 lib/mystring/Makefile.am + create mode 100644 lib/mystring/append.cc + create mode 100644 lib/mystring/assign.cc + copy lib/{config_readint.cc => mystring/count.cc} (53%) + create mode 100644 lib/mystring/fdobuf.cc + create mode 100644 lib/mystring/find_first_ch.cc + create mode 100644 lib/mystring/find_first_of.cc + create mode 100644 lib/mystring/find_last_ch.cc + create mode 100644 lib/mystring/find_last_of.cc + copy lib/{canonicalize.cc => mystring/iter.cc} (53%) + copy lib/{config_readint.cc => mystring/iter.h} (53%) + create mode 100644 lib/mystring/join.cc + create mode 100644 lib/mystring/join.h + create mode 100644 lib/mystring/lower.cc + create mode 100644 lib/mystring/lstrip.cc + create mode 100644 lib/mystring/mystring.cc + create mode 100644 lib/mystring/mystring.h + create mode 100644 lib/mystring/operator_in.cc + create mode 100644 lib/mystring/rep.cc + copy lib/{config_readint.cc => mystring/rep.h} (53%) + create mode 100644 lib/mystring/rstrip.cc + create mode 100644 lib/mystring/strip.cc + create mode 100644 lib/mystring/sub.cc + create mode 100644 lib/mystring/subst.cc + create mode 100644 lib/mystring/trace.h + create mode 100644 lib/mystring/upper.cc + +commit 530d4bd52120d252cdd53fcb71ce611723917e91 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Feb 29 20:58:54 2012 -0600 + + lib/ac: Initial commit of current sources + + lib/ac/dirent.h | 17 +++++++++++++++++ + lib/ac/time.h | 10 ++++++++++ + lib/ac/wait.h | 10 ++++++++++ + 3 files changed, 37 insertions(+) + create mode 100644 lib/ac/dirent.h + create mode 100644 lib/ac/time.h + create mode 100644 lib/ac/wait.h + +commit a935e2d5bbe59ae2002eadb599f7c914530d7562 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Feb 29 20:56:28 2012 -0600 + + lib/cli++: Initial commit of current sources from bglibs + + lib/cli++/Makefile.am | 9 ++ + lib/cli++/cli++.h | 59 +++++++++ + lib/cli++/cli++topod.pl | 213 ++++++++++++++++++++++++++++++ + lib/cli++/clitest.cc | 47 +++++++ + lib/cli++/main.cc | 342 ++++++++++++++++++++++++++++++++++++++++++++++++ + lib/cli++/messages.cc | 44 +++++++ + 6 files changed, 714 insertions(+) + create mode 100644 lib/cli++/Makefile.am + create mode 100644 lib/cli++/cli++.h + create mode 100644 lib/cli++/cli++topod.pl + create mode 100644 lib/cli++/clitest.cc + create mode 100644 lib/cli++/main.cc + create mode 100644 lib/cli++/messages.cc + +commit 860dabe191d28d0002391b3d2395c9524d13f3ff +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Feb 29 20:46:07 2012 -0600 + + Remove unneeded Year 2000 statement + + Makefile.am | 2 +- + YEAR2000 | 10 ---------- + makedist.in | 2 +- + spec | 2 +- + 4 files changed, 3 insertions(+), 13 deletions(-) + delete mode 100644 YEAR2000 + +commit c5d104702d2ff30989368897b9a2b66a1d2544bd +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Feb 29 20:44:45 2012 -0600 + + Update copyright year + + README | 4 ++-- + lib/address-old.cc | 2 +- + lib/address.cc | 2 +- + lib/base64.cc | 2 +- + lib/canonicalize.cc | 2 +- + lib/config_read.cc | 2 +- + lib/config_readint.cc | 2 +- + lib/config_readlist.cc | 2 +- + lib/errcodes.cc | 2 +- + lib/hostname.cc | 2 +- + lib/makefield.cc | 2 +- + lib/selfpipe.cc | 2 +- + lib/setenv.cc | 2 +- + lib/tcpconnect.cc | 2 +- + protocols/protocol.cc | 2 +- + protocols/qmqp.cc | 2 +- + protocols/smtp.cc | 2 +- + src/inject.cc | 2 +- + src/mailq.cc | 2 +- + src/queue.cc | 2 +- + src/send.cc | 2 +- + src/sendmail.cc | 2 +- + 22 files changed, 23 insertions(+), 23 deletions(-) + +commit 88218043763357b339d5cf6d7667444e41e4bbbe +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Feb 25 22:55:17 2012 -0600 + + Reworded the past NEWS items. + + NEWS | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 494f72e2279a90b6b095715929a008e2c8e4708b +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Feb 25 22:48:44 2012 -0600 + + selfpipe: Only use select if the timeout is positive + + If the timeout is zero (or negative), the select will return + immediately. Since the pipe being read from is marked as non-blocking, + this becomes equivalent to just reading from the socket unconditionally + without the select. + + lib/selfpipe.cc | 28 +++++++++++++++------------- + 1 file changed, 15 insertions(+), 13 deletions(-) + +commit 63c54b2ea2cdece784e9f1de61ec0a4a8d73dc87 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Feb 25 22:39:20 2012 -0600 + + send: Fix handling of protocol timeouts + + When the protocol takes too long to send a message to the remote, send + will kill that protocol and retry later. However, it never fully deals + with the signal caused by the child process exiting. So, when it later + resends the message, it appears that the protocol exits immediately, + causing further problems. + + The obvious fix is to make sure we deal with the generated SIGCHLD after + killing the protocol. + + Thanks Nick Leverton <nick@leverton.org> for catching this. + + NEWS | 2 ++ + src/send.cc | 1 + + 2 files changed, 3 insertions(+) + +commit 5c87b96d2d9524b3a059cab5f60aebb5a482449e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Feb 25 13:53:26 2012 -0600 + + Update includes for new ac/time.h include + + Old one was named ac/systime.h + + lib/makefield.cc | 2 +- + src/send.cc | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 8cba9d7f74ba853c30daeafe09f809aa3c2263c1 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Mar 16 16:57:02 2010 -0600 + + Fix handling of whitespace in quoted strings in headers + + NEWS | 2 ++ + lib/address.cc | 8 +++++++- + test/address-test.cc | 9 ++++++++- + 3 files changed, 17 insertions(+), 2 deletions(-) + +commit ec087b5409d038554fadbac73909e83d7905c59a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Feb 5 15:42:20 2010 -0600 + + sync instead of just flush when writing the queue file + + NEWS | 3 +++ + src/queue.cc | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +commit ece5c7bb0d21712272826bc79783c98bf85a658e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Feb 5 15:38:13 2010 -0600 + + Bump version to 1.06 + + NEWS | 5 +++++ + README | 2 +- + configure.in | 2 +- + 3 files changed, 7 insertions(+), 2 deletions(-) + +commit 9bb74bcc71b5fdbdcc52e5e159d1083edab08892 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Oct 13 09:09:23 2007 -0600 + + Modified -send to move permanently failed messages into a failed directory. + + Makefile.am | 2 + + src/send.cc | 114 ++++++++++++++++++++++++++++++++++++++++---------------- + test/functions | 4 +- + test/tests/send | 3 ++ + 4 files changed, 88 insertions(+), 35 deletions(-) + +commit bab6faf0c17a1bdc4685d66c6df953ff8939810d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Oct 12 20:22:55 2007 -0600 + + Added a timestamp to the internal per-message data in -send. + + src/send.cc | 58 ++++++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 36 insertions(+), 22 deletions(-) + +commit 78f74e66c0b28e660aec15f81dbb8607e316fe36 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Oct 12 12:18:53 2007 -0600 + + Modified -dsn to automatically generate DDNs for 4.#.# status codes. + + TODO | 1 - + src/dsn.cc | 46 +++++++++++++++++++++++++++++++++++++--------- + 2 files changed, 37 insertions(+), 10 deletions(-) + +commit 4d17a0346ff11bc47628b33b8700b53c31c1e7e7 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Oct 12 11:45:58 2007 -0600 + + Completed the implementation of nullmailer-dsn + + I'm not particularly happy with the human-readable portion of the + message. This program also needs to be extended to support delay + notifications. + + TODO | 5 +---- + src/dsn.cc | 71 ++++++++++++++++++++++++++++++++++++++++++-------------------- + 2 files changed, 49 insertions(+), 27 deletions(-) + +commit 8705f91a8f48605c817a5782fcdefe1cf268ddfb +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Oct 12 10:32:06 2007 -0600 + + Renamed nullmailer-bounce to -dsn, as it will be used to create DDNs too. + + .gitignore | 1 + + src/Makefile.am | 6 +-- + src/bounce.cc | 90 --------------------------------- + src/dsn.cc | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 158 insertions(+), 93 deletions(-) + delete mode 100644 src/bounce.cc + create mode 100644 src/dsn.cc + +commit 5ac20a731071d2c2c7f10171a07a4eddce56c76c +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Oct 12 10:29:34 2007 -0600 + + Allow make_date to use timestamps other than now. + + lib/makefield.cc | 5 +++-- + lib/makefield.h | 2 +- + 2 files changed, 4 insertions(+), 3 deletions(-) + +commit 2752949f790f1f11ff532a97da954e72b9fe3a69 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Oct 12 09:52:04 2007 -0600 + + Add the PID to the boundary string. + + lib/makefield.cc | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit 663c30da1177b0d2bd50bf95f9d0549eeb5f3af8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 15:19:36 2007 -0600 + + Started implementation of the nullmailer-bounce program. + + src/Makefile.am | 4 +++ + src/bounce.cc | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 94 insertions(+) + create mode 100644 src/bounce.cc + +commit 3d2d9a4e4ff7033edc6a221961a4906d4bb5baf4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 15:18:34 2007 -0600 + + Added a simple boundary string generator make_boundary(). + + lib/makefield.cc | 10 ++++++++++ + lib/makefield.h | 1 + + 2 files changed, 11 insertions(+) + +commit 9bcc733516a02260d3e468a87486aed9d0a3b621 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Oct 19 11:00:09 2009 -0600 + + Stamped README with today's date + + README | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 6450c36e5605ce05e2ffbb090982ea0642d45bda +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 17 16:50:31 2008 -0600 + + Removed unnecessary FIXME comment in lib/address.cc + + lib/address.cc | 2 -- + 1 file changed, 2 deletions(-) + +commit 2b339dcf76b2d8dd6df6e08549b2d4c75c87e1ad +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 17 16:41:58 2008 -0600 + + Set umask in nullmailer-queue, just for safety. + + src/queue.cc | 1 + + 1 file changed, 1 insertion(+) + +commit 218f9921688643c4bb63ebf1df65a233ba0a2070 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 17 16:13:17 2008 -0600 + + Replaced some single-byte string constants with characters in lib/address.cc + + lib/address.cc | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +commit 8a44d18869dcfb5a9c46e878e3a17334ab8a49b0 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 17 15:24:41 2008 -0600 + + Fixed handling of phrases with mixed spacing in the address parser. + + This change introduces a flag to the token structure to indicate if the + token was preceded by whitespace. That flag is used later to calculate + if a space should be added back into the reconstructed address field. + + lib/address.cc | 62 +++++++++++++++++++++++++++++----------------------- + test/address-test.cc | 6 +++++ + 2 files changed, 41 insertions(+), 27 deletions(-) + +commit 2d87bf661aa36bf1adb694fc028c4de85658b723 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 17 13:50:24 2008 -0600 + + Started fixing phrases containing periods, such as abbreviations. + + NEWS | 2 ++ + lib/address.cc | 24 ++++++++++++++++-------- + test/address-test.cc | 3 +++ + 3 files changed, 21 insertions(+), 8 deletions(-) + +commit 64bf159f68314540c6631b61e96d5ac2f880f80d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 17 13:16:43 2008 -0600 + + Fixed handling of periods (and other specials) inside quotes. + + lib/address.cc | 4 ++-- + test/address-test.cc | 6 ++++++ + 2 files changed, 8 insertions(+), 2 deletions(-) + +commit f8ec121071c7149f07b71eeabe7f9e6bcc84a755 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Apr 17 11:28:50 2008 -0600 + + Eliminate the anode constructor that doesn't include a string. + + lib/address.cc | 16 +++++----------- + 1 file changed, 5 insertions(+), 11 deletions(-) + +commit 55ff89634392411830b8360dd4f4da98af2b2b59 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Apr 16 09:57:57 2008 -0600 + + Fixed use-after-destruct bug in address parsing tracing. + + lib/address.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 441ac8b60121c728cb7f1f0ef5396fc4ad2787ea +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Apr 16 16:42:31 2008 -0600 + + Fixed handling of TM_HAS_ISDST on Solaris. + + Thanks to John Coy <johncoy@anc.net> for pointing this out. + + NEWS | 2 ++ + lib/makefield.cc | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +commit 381cce827b8516fbd7b2f9d891214c0b738b2431 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Oct 12 20:18:20 2007 -0600 + + Added a selftest for -send. + + test/tests/send | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + create mode 100644 test/tests/send + +commit a3f409909ded9c9ca2b22e8c16a61c4a42ca665d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Oct 12 20:11:02 2007 -0600 + + Switch to using supervise for running subprocesses in tests. + + test/functions | 37 ++++++++++++++++++++++--------------- + test/tests/protocols | 6 ++---- + 2 files changed, 24 insertions(+), 19 deletions(-) + +commit 6af25d1743a2a99605add05becd7f1407184a050 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Oct 12 18:57:50 2007 -0600 + + Reordered the status error codes to group the permanent ones. + + lib/errcodes.cc | 48 ++++++++++++++++++++++++++---------------------- + lib/errcodes.h | 17 +++++++++++------ + src/send.cc | 2 +- + 3 files changed, 38 insertions(+), 29 deletions(-) + +commit 4a40f14aa68369a642216dfcf4c38eef30516c2a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Oct 12 09:50:06 2007 -0600 + + Tweaked the make_messageid function to make it more code efficient. + + lib/makefield.cc | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +commit 29e724376ff61d434b11e1f47c71c373d6f4b82a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 23:01:55 2007 -0600 + + Fixed compilation of src/selfpipe.cc on Solaris and other OSes. + + NEWS | 1 + + lib/selfpipe.cc | 1 + + 2 files changed, 2 insertions(+) + +commit 329313e7c642081d491b3c26d0969fd7cdc7a60e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 23:01:17 2007 -0600 + + Bumped version to 1.05 + + NEWS | 6 ++++++ + configure.in | 2 +- + 2 files changed, 7 insertions(+), 1 deletion(-) + +commit 3f17550ee9ba94dbf5d8582929f84cc5711d6971 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 17:33:52 2007 -0600 + + Stamped many files with today's date/year. + + README | 4 ++-- + lib/address-old.cc | 2 +- + lib/address.cc | 2 +- + lib/base64.cc | 2 +- + lib/config_read.cc | 2 +- + lib/config_readint.cc | 2 +- + lib/config_readlist.cc | 2 +- + lib/errcodes.cc | 2 +- + lib/hostname.cc | 2 +- + lib/makefield.cc | 2 +- + lib/setenv.cc | 2 +- + lib/tcpconnect.cc | 2 +- + protocols/protocol.cc | 2 +- + protocols/qmqp.cc | 2 +- + protocols/smtp.cc | 2 +- + src/inject.cc | 2 +- + src/mailq.cc | 2 +- + src/queue.cc | 2 +- + src/sendmail.cc | 2 +- + 19 files changed, 20 insertions(+), 20 deletions(-) + +commit 4ca905042fff71cb1a7a674502b442b194f827dd +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 17:33:39 2007 -0600 + + Added some missing bits needed for distribution. + + lib/Makefile.am | 2 +- + spec | 4 +--- + 2 files changed, 2 insertions(+), 4 deletions(-) + +commit 1c5e462c86e567ff4e468656c2c26bcd246e1ce1 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 15:50:00 2007 -0600 + + Fixed up some test function includes. + + test/functions | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +commit efc6fe62282ed60eee927bd272faa98293f60943 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 15:49:17 2007 -0600 + + Added a .gitignore file to let get ignore more files. + + .gitignore | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + create mode 100644 .gitignore + +commit 7bed03ab4b0f4ba72ecbf2f01b82a3a42a200124 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 15:48:54 2007 -0600 + + Updated the TODO notes a bit. + + TODO | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +commit 1a80bbef3ad9dc7451e262f681e85945702a4ceb +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 15:48:20 2007 -0600 + + Added the standard GPL copying document. + + COPYING | 340 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 340 insertions(+) + create mode 100644 COPYING + +commit 2210203cae988833b6e468c508fb2ce52623a98f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 15:48:02 2007 -0600 + + Added a simple INSTALL document. + + INSTALL | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + create mode 100644 INSTALL + +commit f5041c11b8f8543948a09fa3bf06e147226ba382 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 15:47:42 2007 -0600 + + Removed an unneeded header from src/queue.cc + + src/queue.cc | 1 - + 1 file changed, 1 deletion(-) + +commit c3dd869824827c2ddf74a5d45f7177912bdb81dd +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 15:47:21 2007 -0600 + + Fixed a double space in the mailq output, and added a test script. + + src/mailq.cc | 2 +- + test/tests/mailq | 10 ++++++++++ + 2 files changed, 11 insertions(+), 1 deletion(-) + create mode 100644 test/tests/mailq + +commit bd8c99e3898710b542fd5a6f08f98ffdf3e933f8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 14:36:12 2007 -0600 + + Added a header for lib/makefield.cc + + lib/makefield.cc | 4 +--- + lib/makefield.h | 7 +++++++ + src/inject.cc | 10 ++++------ + 3 files changed, 12 insertions(+), 9 deletions(-) + create mode 100644 lib/makefield.h + +commit c04e92eb8bcd99f16a908e48e8bee1673488ccf8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 12:13:22 2007 -0600 + + Do not canonicalize *@localhost addresses. + + NEWS | 3 +++ + doc/nullmailer-inject.1 | 4 +++- + lib/canonicalize.cc | 4 ++-- + test/tests/inject/from | 4 ++++ + test/tests/inject/sender | 4 ++++ + 5 files changed, 16 insertions(+), 3 deletions(-) + +commit 5038832d2067dbf30903bc2273b8673904fab11b +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 10:40:29 2007 -0600 + + Documented the helohost config file that nullmailer-send uses. + + TODO | 12 +++++++++--- + doc/nullmailer-send.8 | 10 ++++++++++ + 2 files changed, 19 insertions(+), 3 deletions(-) + +commit 357e7086733b25ab1116405502030c75993fb784 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 10:40:05 2007 -0600 + + Fixed nullmailer-send to reread helohost along with the other config files. + + src/send.cc | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +commit 07300026f7dfbf889b56ce45b0dd7a8160ac8aee +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 10:38:55 2007 -0600 + + Make a hanging test protocol server less likely in tests/protocols. + + The previous test script set up an exit function to kill the test + protocol server *after* sleeping for 1 second. If the script was + interrupted during that sleep, the server wouldn't get killed properly. + + test/tests/protocols | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 89a18d52833e65565031ed7a3cd61ff55fcfb151 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 10:08:11 2007 -0600 + + Added support for reporting the sender and recipients in mailq. + + NEWS | 2 ++ + src/mailq.cc | 12 +++++++++++- + 2 files changed, 13 insertions(+), 1 deletion(-) + +commit bb508024b20ee63e9f99e13159969467ab7145e3 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Oct 9 09:09:00 2007 -0600 + + Report system errors in more cases in nullmailer-send. + + src/send.cc | 21 +++++++++------------ + 1 file changed, 9 insertions(+), 12 deletions(-) + +commit 695d263cb625df30c9020a03d4eeee09972a30d4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Oct 7 23:11:51 2007 -0600 + + Fix "missing sentinel in function call" warning in src/inject.cc + + src/inject.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 0c747e5e565256cd911dfaec96db8c188c462eb7 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Apr 10 00:03:25 2007 +0000 + + Added a send timeout in nullmailer-send, to kill sending messages that + stall. + + NEWS | 3 ++ + doc/nullmailer-send.8 | 10 +++++ + lib/Makefile.am | 1 + + lib/selfpipe.cc | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++ + lib/selfpipe.h | 16 ++++++++ + src/send.cc | 31 +++++++++++++++- + 6 files changed, 161 insertions(+), 1 deletion(-) + create mode 100644 lib/selfpipe.cc + create mode 100644 lib/selfpipe.h + +commit 2971ceacb9ccd75126996669a0ed92e8b9a6dc8e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 9 23:28:54 2007 +0000 + + Added support in nullmailer-inject for $NULLMAILER_QUEUE to name the + program which is used to queue messages. + + NEWS | 2 ++ + doc/nullmailer-inject.1 | 6 ++++++ + src/inject.cc | 18 ++++++++++-------- + test/functions | 25 ++++++++++++++++++++----- + test/tests/inject/queue | 14 ++++++++++++++ + 5 files changed, 52 insertions(+), 13 deletions(-) + create mode 100644 test/tests/inject/queue + +commit 7daab6d2e608a08b42ee61751def5b3231a5e01b +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Apr 9 16:01:16 2007 +0000 + + Bumped version to 1.04 + + NEWS | 6 ++++++ + README | 2 +- + configure.in | 2 +- + 3 files changed, 8 insertions(+), 2 deletions(-) + +commit 99833fecba790016eb54869fe342205e1b8055c5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 29 22:16:35 2006 +0000 + + Added missing setenv.h source file. + + lib/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b5ee39825d5e5835b06bb187b4b9fdc5dd8fa126 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 29 21:04:48 2006 +0000 + + Test for the use of getpwnam instead of "unknown" as a last resort on + sender addresses. + + test/tests/inject/from | 4 ++-- + test/tests/inject/sender | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +commit 2dc75a869c1d04f9fdd9a2ee20fee0edeec1ff30 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 29 19:54:12 2006 +0000 + + Bumped date stamp on the README + + README | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6ceeeffe2e118bad2407ed869e969044ee78dc15 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 29 19:53:40 2006 +0000 + + Revised how I want to handle bouncing messages. + + TODO | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit fefb4a02f65431fda75f1a93a2a3c4288ba39df8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 29 19:30:33 2006 +0000 + + If the sender name cannot be determined from the environment + variables, try to pull it from /etc/passwd before using "unknown". + Thanks Roderick Schertler <roderick@argon.org> + + Mail from cron gets an envelope sender address of "unknown" because it + doesn't set $LOGNAME or $USER in the environment. This patch fixes it + by having nullmailer-inject try getpwnam() for the name if the + environment variables aren't set. + + http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=218326 + + NEWS | 4 ++++ + doc/nullmailer-inject.1 | 5 +++-- + src/inject.cc | 5 +++++ + 3 files changed, 12 insertions(+), 2 deletions(-) + +commit 0a65f1b7513554aa4794a65b108f33ac486cd0f0 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jun 27 23:22:42 2006 +0000 + + Fixed netstring length bug in QMQP sending module. + + NEWS | 2 ++ + protocols/qmqp.cc | 4 ++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +commit b47012b6aab40fc900d822b2c9909e011ff4d1ab +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jun 27 23:22:13 2006 +0000 + + Fixed compile breakage on Solaris due to use of setenv. + + NEWS | 2 ++ + lib/Makefile.am | 3 ++- + lib/{config_readint.cc => setenv.cc} | 29 +++++++++++++++++------------ + lib/setenv.h | 6 ++++++ + src/send.cc | 1 + + src/sendmail.cc | 20 +------------------- + 6 files changed, 29 insertions(+), 32 deletions(-) + copy lib/{config_readint.cc => setenv.cc} (64%) + create mode 100644 lib/setenv.h + +commit cde4bc394cbdb05ffebe96659fcf400b297b8251 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jun 23 18:40:00 2006 +0000 + + Fixed the SMTP protocol module to send EHLO instead of HELO when doing + authentication. Thanks to Norbert Tretkowski <norbert@tretkowski.de> + for the suggestion. + + NEWS | 6 +++++- + protocols/smtp.cc | 4 +++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +commit 8ac930b89d7ad4a5f1ff2db6c2dcc223e518156c +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jun 23 15:20:29 2006 +0000 + + Added support for the SMTP AUTH LOGIN method. + + NEWS | 2 ++ + doc/nullmailer-send.8 | 7 +++++++ + protocols/protocol.cc | 5 ++++- + protocols/protocol.h | 3 +++ + protocols/smtp.cc | 31 ++++++++++++++++++++----------- + 5 files changed, 36 insertions(+), 12 deletions(-) + +commit 8910fae6567878c83972a729d812330878f3af2f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 22 17:08:08 2006 +0000 + + Fixed the SMTP protocol module to send QUIT on protocol failures. + + NEWS | 1 + + protocols/smtp.cc | 2 ++ + 2 files changed, 3 insertions(+) + +commit f6352bb34ee4460833b436f0a42e57094f85ad11 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 22 17:07:34 2006 +0000 + + Bumped version to 1.03 + + NEWS | 6 ++++++ + README | 2 +- + configure.in | 2 +- + 3 files changed, 8 insertions(+), 2 deletions(-) + +commit 5d7dc2399ce42378497cd8d601cd95800d1aa1ad +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 22 17:00:19 2006 +0000 + + Rename Copyright to License in spec. + + spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 031244d3092619ead6285b1d2eb61ba089264b80 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jan 10 04:31:19 2006 +0000 + + Bumped the date and version on the README. + + README | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit c7789de1ff5957c8db6995317947cbb7f4d5191e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Dec 7 22:59:13 2005 +0000 + + Fixed bug in SMTP AUTH that would cause SMTP sending to crash with a + segfault when it was used. + + NEWS | 2 ++ + protocols/smtp.cc | 6 +++++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +commit 185b75a8bac9dbe8be395b392de1934c459618dc +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Dec 7 22:58:24 2005 +0000 + + Bumped version to 1.02 + + NEWS | 6 ++++++ + configure.in | 2 +- + 2 files changed, 7 insertions(+), 1 deletion(-) + +commit 08ca3d9b16eab9d148e5963e768c41ab4b821074 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Nov 10 16:12:06 2005 +0000 + + Adjusted email addresses to point to untroubled.org + + AUTHORS | 2 +- + BUGS | 2 +- + README | 2 +- + lib/address-old.cc | 6 +++--- + lib/address.cc | 6 +++--- + lib/base64.cc | 6 +++--- + lib/canonicalize.cc | 6 +++--- + lib/config_read.cc | 6 +++--- + lib/config_readint.cc | 6 +++--- + lib/config_readlist.cc | 6 +++--- + lib/errcodes.cc | 6 +++--- + lib/hostname.cc | 6 +++--- + lib/makefield.cc | 6 +++--- + lib/tcpconnect.cc | 6 +++--- + makedist.in | 2 +- + protocols/protocol.cc | 6 +++--- + protocols/qmqp.cc | 6 +++--- + protocols/smtp.cc | 6 +++--- + spec | 6 +++--- + src/inject.cc | 6 +++--- + src/mailq.cc | 6 +++--- + src/queue.cc | 6 +++--- + src/send.cc | 6 +++--- + src/sendmail.cc | 6 +++--- + test/tests/protocols | 8 ++++---- + 25 files changed, 68 insertions(+), 68 deletions(-) + +commit d69ef12cb81402bf881f064cb0cc64c947f2bf48 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Nov 10 16:08:00 2005 +0000 + + Updated the release date in the README file. + + README | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2f121ae04b3c9345fc9594ff23b029f67908adbb +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Nov 10 16:07:00 2005 +0000 + + Touched up note about SMTP AUTH implementation, since it has been + heavily modified. + + NEWS | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit d88aa91ae567b2fb79980c72bbde94dce189795e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Nov 7 18:31:35 2005 +0000 + + Roll back the mistakenly increased value of cli_args_max + in protocols/protocol.cc + + protocols/protocol.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit fa37094d53833ef3c8d71a5e11ab9718f540c5a7 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Nov 7 18:30:24 2005 +0000 + + Break up the --auth option to protocols into --user and --pass. + + doc/nullmailer-send.8 | 2 +- + protocols/protocol.cc | 9 ++++++--- + protocols/protocol.h | 4 +++- + protocols/smtp.cc | 8 ++------ + 4 files changed, 12 insertions(+), 11 deletions(-) + +commit a4b284f66d595dff455bf42e7c7ce0e0b5b78256 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Nov 2 17:58:50 2005 +0000 + + Simplified the logic of breaking the "user,pass" string into its two parts. + + protocols/smtp.cc | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 203770e20d27331290ce3e01efc512c8cc9d6286 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Nov 2 17:57:22 2005 +0000 + + Moved the common "auth" global into protocol.cc, making it default to + NULL instead of an empty string. + + protocols/protocol.cc | 1 + + protocols/protocol.h | 2 +- + protocols/qmqp.cc | 1 - + protocols/smtp.cc | 3 +-- + 4 files changed, 3 insertions(+), 4 deletions(-) + +commit 3cad91f34674656cbadd9f26584e968fa323aa84 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Nov 2 17:52:21 2005 +0000 + + Broken the base64 conversion out of protocols/smtp.cc (and simplified it + greatly in the process). + + TODO | 2 -- + lib/Makefile.am | 1 + + lib/base64.cc | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ + lib/base64.h | 10 +++++++++ + protocols/smtp.cc | 67 +++++-------------------------------------------------- + 5 files changed, 80 insertions(+), 63 deletions(-) + create mode 100644 lib/base64.cc + create mode 100644 lib/base64.h + +commit e6a655c635fce55aa4d365ed8d689777795ae0a4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Nov 2 17:11:22 2005 +0000 + + Added support for SMTP AUTH PLAIN + Thanks Ace Jones <ace.j@hotpop.com> + + NEWS | 2 ++ + TODO | 4 +++ + doc/nullmailer-send.8 | 5 ++-- + protocols/protocol.cc | 4 ++- + protocols/protocol.h | 1 + + protocols/qmqp.cc | 1 + + protocols/smtp.cc | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 7 files changed, 83 insertions(+), 3 deletions(-) + +commit a2cfd3adb3650e4fadfda84ec6c4436035a5d889 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Nov 2 16:50:37 2005 +0000 + + Fixed compile error in lib/list.h + + NEWS | 1 + + lib/list.h | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +commit e24ff7d1187fff34bacee4b3e9f68494a3fb1f1e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Nov 2 16:50:11 2005 +0000 + + Bumped version to 1.01 + + NEWS | 6 ++++++ + README | 2 +- + configure.in | 2 +- + 3 files changed, 8 insertions(+), 2 deletions(-) + +commit e96902b673a4e2494ca245d29b7bd47e67e8d8a2 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Feb 28 17:54:04 2005 +0000 + + Fixed up lib Makefile to properly dist the ac directory. + + lib/Makefile.am | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 8e91d48269e281d31bb27bcfa8e08771d23bdb41 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Feb 28 17:49:53 2005 +0000 + + Renamed ac/time.h to ac/systime.h to prevent #include recursion. + + lib/makefield.cc | 2 +- + src/send.cc | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 759016a2030267b6effb407e626f696db26ce9ec +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Feb 28 17:28:34 2005 +0000 + + Updated dates, version, and em.ca URLs. + + README | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 4a4da64bc6e79126d6684b9973aa4bfb1672c658 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Feb 28 17:28:11 2005 +0000 + + Removed note about my daemontools RPMs as they are no longer really mailtained. + + HOWTO | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit 3fc2cc552bead7c3c2ddc797ccc4e28b786ee4f0 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Feb 28 17:27:45 2005 +0000 + + Added some TODOs for protocols, I just want to get 1.00 out the door. + + TODO | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 2fc95aa6bdf7937dd20573e435776e66767b0639 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Feb 28 17:20:39 2005 +0000 + + Updated links to em.ca to untroubled.org + + makedist.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 48ed6d1ab193122319518d8969997a7634816fdf +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Feb 28 17:20:15 2005 +0000 + + Removed note about documentation fix. + + TODO | 2 -- + 1 file changed, 2 deletions(-) + +commit e7466bbfa007c6c2507230d173f5b7fd6ed25e4f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Feb 26 00:14:31 2005 +0000 + + Bumped version to 1.00 (no RC status) + + NEWS | 5 +---- + README | 2 +- + configure.in | 2 +- + 3 files changed, 3 insertions(+), 6 deletions(-) + +commit 7d747a340849ff4da7f4cfcc3dd73b15cc1f4ae5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Feb 26 00:07:54 2005 +0000 + + Removed extra TODO item as nullmailer-inject already handles it. + + TODO | 3 --- + 1 file changed, 3 deletions(-) + +commit 7e937ae6838f4f048eada733ee3834d530a1c04a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Feb 26 00:06:16 2005 +0000 + + Fixed bug in handling headers containing CR+LF line endings. + + NEWS | 2 ++ + TODO | 3 --- + src/inject.cc | 2 +- + 3 files changed, 3 insertions(+), 4 deletions(-) + +commit c67c5eaad79527bce438b99040e3c2c837fbd318 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Feb 25 23:52:31 2005 +0000 + + Use a plain grep instead of formail to extract header entries. + + test/functions | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 38b45971581c15e86248ec96e8b650653de7c2c4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Feb 25 23:52:15 2005 +0000 + + Use the "-n" argument to head and tail commands. + + test/tests/inject/recips | 2 +- + test/tests/inject/sender | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +commit 0cdb3f5ea009a7ace06f1ea34721fc064e87e85c +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Feb 25 23:50:11 2005 +0000 + + Fixed bug in header parsing that would cause the last header line to + be repeated if there was no body. + + NEWS | 3 +++ + src/inject.cc | 1 + + 2 files changed, 4 insertions(+) + +commit ff8d1b990502c773124ebd024a5dc027260b98dd +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Feb 25 22:33:59 2005 +0000 + + Adjusted usage for newest automake 1.9 and autoconf 2.59 tools. + + acconfig.h | 21 --------------------- + acinclude.m4 | 58 +++++++++++++++++++++++++--------------------------------- + configure.in | 8 +++++--- + 3 files changed, 30 insertions(+), 57 deletions(-) + delete mode 100644 acconfig.h + +commit 02301e054d43c30b605ff6e53e020b30bf80feb4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Feb 21 22:23:55 2005 +0000 + + Fixed problem with multiple arguments to protocol modules. + Thanks Sascha Silbe <sascha-ml-nullmailer@silbe.org> + + NEWS | 3 +++ + src/send.cc | 4 ++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +commit b6ec5afabea7bb06d19d78ac3e64e4f7ee13bc61 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Feb 21 16:56:44 2005 +0000 + + Fixed extraneous spaces in SMTP sender. + + NEWS | 2 ++ + protocols/smtp.cc | 6 +++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +commit 22c89ba9c04455da98b2bba073e1e74ec9bfe3cb +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Feb 12 23:47:07 2003 +0000 + + Added reference to "me" config file in top-level documentation. + + doc/nullmailer.7 | 1 + + 1 file changed, 1 insertion(+) + +commit 1ec58eba7492a3a17bb2609e87c7080292cba95d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 15 17:34:45 2003 +0000 + + Fixed a bug in reporting errors in the result string -- they do need a + newline. + + test/address-test.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 162bae93b1c6376d7104bd9572e80f09de40d39b +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jan 15 17:34:08 2003 +0000 + + Fixed the address parser handling domain names with trailing periods. + + NEWS | 2 ++ + lib/address.cc | 5 +++-- + test/address-test.cc | 8 ++++++-- + 3 files changed, 11 insertions(+), 4 deletions(-) + +commit 499aaf4797e2fb4c007612b495324c24ccc28d57 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Jan 13 20:21:50 2003 +0000 + + Fixed the warning on the cli_options list end marker. + Patch from Martin Godisch <martin@godisch.de> + + protocols/protocol.cc | 2 +- + src/inject.cc | 2 +- + src/sendmail.cc | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +commit 9a02750cc3cbe0f1b8ef6743470b2c6b84cd29da +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Jan 12 04:31:15 2003 +0000 + + Handle the "-bs" flag in the sendmail wrapper by dieing when we see it. + http://bugs.debian.org/170079 + Patch from Martin Godisch <martin@godisch.de> + + NEWS | 2 ++ + src/sendmail.cc | 7 ++++++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +commit a1763f70cd0407894320de203ebf7541a78a7339 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Jan 12 04:27:24 2003 +0000 + + Fixed some compile warnings. + Patch from Martin Godisch <martin@godisch.de> + + lib/list.h | 9 +++++---- + src/sendmail.cc | 2 +- + 2 files changed, 6 insertions(+), 5 deletions(-) + +commit 83dcee3a92c4acedd8a68f4e544d07b9e30a2561 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Jan 12 04:25:07 2003 +0000 + + Made permissions on queued files more strict. + http://bugs.debian.org/164951 + + NEWS | 2 ++ + src/queue.cc | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +commit 6382e441d3a332bf170bc9eeb25186ee45bb6090 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Jan 12 04:24:18 2003 +0000 + + Bumped version up to 1.00RC8 + + NEWS | 11 ++++++++--- + configure.in | 2 +- + 2 files changed, 9 insertions(+), 4 deletions(-) + +commit 1aeae0c1cca00e85fb620212a49c8d9b73627358 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 3 23:10:21 2003 +0000 + + Removed old items. + + TODO | 20 +++----------------- + 1 file changed, 3 insertions(+), 17 deletions(-) + +commit 0d8c3e7333b07cfb23ab431ceb1a288a8d122301 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 3 23:09:46 2003 +0000 + + Added note about setting up the "me" config file. + + HOWTO | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +commit 9b80fcc1c41399f83c476bf445bbf331dbb142ec +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 3 21:49:25 2003 +0000 + + Bumped up the version to 1.00RC7 + + README | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 35d3211c2104584cc2bf3982680a452afb3e6515 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 3 21:49:13 2003 +0000 + + Added the ChangeLog.old file to the list of extras. + + makedist.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ff31729908d8581446c724acb25b5571bd65f017 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 3 21:02:46 2003 +0000 + + Updated dates on copyright marks. + + README | 4 ++-- + lib/address-old.cc | 2 +- + lib/address.cc | 2 +- + lib/canonicalize.cc | 2 +- + lib/config_read.cc | 2 +- + lib/config_readint.cc | 2 +- + lib/config_readlist.cc | 2 +- + lib/errcodes.cc | 2 +- + lib/hostname.cc | 2 +- + lib/makefield.cc | 2 +- + lib/tcpconnect.cc | 2 +- + makedist.in | 2 +- + protocols/protocol.cc | 2 +- + protocols/qmqp.cc | 2 +- + protocols/smtp.cc | 2 +- + src/inject.cc | 2 +- + src/mailq.cc | 2 +- + src/queue.cc | 2 +- + src/send.cc | 2 +- + src/sendmail.cc | 2 +- + 20 files changed, 21 insertions(+), 21 deletions(-) + +commit 43be0087a7242853132c6fc6a53a132a5a146bf7 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 3 21:02:18 2003 +0000 + + Renamed ChangeLog to allow use of svn-generated ChangeLog + + ChangeLog => ChangeLog.old | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) + rename ChangeLog => ChangeLog.old (100%) + +commit 376394e1af0f25e8ea0b168da70a79e9cffa6b08 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 3 20:51:59 2003 +0000 + + Added a one-shot mode to nullmailer-send. + + NEWS | 3 +++ + doc/nullmailer-send.8 | 4 ++++ + src/send.cc | 1 + + 3 files changed, 8 insertions(+) + +commit ab8a90edce7c7f445e9729489b76e571f337f226 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Jan 3 20:40:21 2003 +0000 + + Reset reload_files to false when the files are reloaded. + + src/send.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit f2291a8bcc42973f02ba8f1d09e4cb46cb6c6862 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Dec 27 14:28:33 2002 +0000 + + Fixed typo in smtp.cc -- "me" should be "hh". + + NEWS | 2 ++ + protocols/smtp.cc | 3 +-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +commit b8c300ae4d5f6ee27c133a61d463ea0dd75ecad0 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Dec 27 14:24:33 2002 +0000 + + Bumped up version to 1.00RC7 + + NEWS | 12 +++++++++--- + configure.in | 2 +- + 2 files changed, 10 insertions(+), 4 deletions(-) + +commit b39514ec1935d22571c94ccd187a3c7f7d04c834 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 20:50:55 2002 +0000 + + Removed CVS note. + + README | 4 ---- + 1 file changed, 4 deletions(-) + +commit 4731fbd50f1e8ce9891cef664098a7f28def057f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 20:50:42 2002 +0000 + + Set date to today. + + README | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 851cbab77a8f6018052d3a4df4a370b1eb7fd4b0 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 18:25:01 2002 +0000 + + Added note about new protocol module messages, new control file, and + FutureQuest sponsorship. + + NEWS | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit 8dc1b3d69d0192db41f9bafc7b8a0cc7d8d8c178 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 18:22:39 2002 +0000 + + Fixups: also show the failure message, and use the proper exit code. + + protocols/protocol.cc | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +commit 7868ecfff640373774da7aa88f74ed0aaf6a183d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 18:19:58 2002 +0000 + + Show success messages as well. + + protocols/protocol.cc | 6 ++++++ + protocols/protocol.h | 1 + + protocols/qmqp.cc | 2 +- + protocols/smtp.cc | 28 ++++++++++++++-------------- + 4 files changed, 22 insertions(+), 15 deletions(-) + +commit d66b1aec1546c236dfc033ee69e815a99147df50 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 18:14:11 2002 +0000 + + Removed the superfluous "QUIT" command. + + protocols/smtp.cc | 1 - + 1 file changed, 1 deletion(-) + +commit 3f030145f445adbbda33670f1ee620a776c4959a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 18:11:57 2002 +0000 + + Output error messages when exiting with a failure code. + + protocols/protocol.cc | 18 +++++++++++++----- + protocols/protocol.h | 6 ++++-- + protocols/qmqp.cc | 27 +++++++++++++-------------- + protocols/smtp.cc | 17 ++++++++--------- + 4 files changed, 38 insertions(+), 30 deletions(-) + +commit cf5c0011a4b88eb89582b1f61d5b0f7916f59000 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 18:11:03 2002 +0000 + + Allow protocol modules to output their own error messages. + + src/send.cc | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit c284b3127232e5f3b125d6577b39cb8fa5c0e00d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 17:52:49 2002 +0000 + + Make sure to remove default{domain,host} before testing use of "me". + + test/tests/inject/from | 1 + + test/tests/inject/sender | 1 + + 2 files changed, 2 insertions(+) + +commit dde9fa660686a66ae8ef11ce8dff3b5f4f95d51f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 17:52:22 2002 +0000 + + Use the "me" control as the hostname to remap with adminaddr. + + doc/nullmailer-queue.8 | 9 +++------ + src/queue.cc | 4 +--- + 2 files changed, 4 insertions(+), 9 deletions(-) + +commit 25c573a9cbdf65536e2804759544d5d7404fae4b +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 17:51:17 2002 +0000 + + Use the "me" control as the idhost, not a default file. + + src/inject.cc | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 45943686ddb59555396a93757150f903de3c89a5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 17:50:38 2002 +0000 + + Fixed up and documented the default host/domain rules. + + doc/nullmailer-inject.1 | 12 ++++++++---- + lib/hostname.cc | 15 +++++++++++---- + 2 files changed, 19 insertions(+), 8 deletions(-) + +commit f6c69210eb981915189202e545691b867e82dfbd +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 17:38:45 2002 +0000 + + Only append a "." to the domain name (when appending the defaultdomain) + if it isn't empty. + + lib/canonicalize.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ecde7805dd7a5a81a9a72e3efcc5b3c7bdeea7a8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 17:27:33 2002 +0000 + + Auto-create /etc/nullmailer/{me,defaultdomain} on install. + + spec | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit 9d9cf4abe2823f064490353e65050454e03ec5dd +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 17:22:36 2002 +0000 + + Fixed up tests for the new "me" control file. + + test/functions | 4 ++-- + test/tests/inject/from | 5 ++--- + test/tests/inject/message-id | 5 ++--- + test/tests/inject/sender | 15 ++++----------- + test/tests/protocols | 1 + + test/tests/queue/rewrite | 3 +-- + 6 files changed, 12 insertions(+), 21 deletions(-) + +commit 2dcada1a8420f0cd2071f7d5400d36d90da9168f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 16:59:48 2002 +0000 + + Fixup the tests for the more strict bash2 syntax. + + test/functions | 10 ++++++---- + test/tests/inject/bad-headers | 2 +- + test/tests/inject/date | 2 +- + test/tests/inject/from | 2 +- + test/tests/inject/message-id | 2 +- + test/tests/inject/recips | 6 +++--- + test/tests/inject/return-path | 2 +- + test/tests/inject/sender | 6 +++--- + 8 files changed, 17 insertions(+), 15 deletions(-) + +commit a608374d86fa96f1684ac9a97e20ee5ad905c797 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Dec 23 16:59:26 2002 +0000 + + Skip over the .svn directory instead of the CVS directory. + + test/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b969ad0011e096337e1df8b726a4dab31009ac5e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Dec 17 17:49:04 2002 +0000 + + Renamed lib/cli to lib/cli++ + + configure.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit beec6d81cdddd0e97075f0376a7695f8eace77d8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Dec 15 05:36:45 2002 +0000 + + Renamed lib/cli to lib/cli++ to match the current sources. + + lib/Makefile.am | 2 +- + protocols/Makefile.am | 6 +++--- + protocols/protocol.cc | 2 +- + src/Makefile.am | 6 +++--- + src/inject.cc | 2 +- + src/sendmail.cc | 2 +- + 6 files changed, 10 insertions(+), 10 deletions(-) + +commit 6236adb6505b8de30d84cd21c77e2fde431813ef +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Dec 15 05:29:43 2002 +0000 + + *** empty log message *** + + TODO | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit d61f752fbb528a39e25dee76318ee0710c86761e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Dec 15 05:29:39 2002 +0000 + + Added some empty address list tests. + + test/address-test.cc | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit f6bd9e96236bc9d15ace31b3a9bcf8f417bd2453 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Dec 15 05:29:06 2002 +0000 + + Clarified documentation. + + doc/nullmailer-inject.1 | 3 +++ + doc/nullmailer-send.8 | 13 ++++++++++--- + 2 files changed, 13 insertions(+), 3 deletions(-) + +commit da5599048065408b11898be922d8666b9ac42fb3 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Dec 15 05:28:13 2002 +0000 + + Remove the CXXLINK hack that prevents compilation with newer versions of + gcc. + + protocols/Makefile.am | 1 - + src/Makefile.am | 1 - + test/Makefile.am | 1 - + 3 files changed, 3 deletions(-) + +commit 7b404a44924cab6728dce8b44ad87148ab12a3a4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Dec 15 05:27:40 2002 +0000 + + Pass $HELOHOST on to the protocol modules. + + protocols/smtp.cc | 3 ++- + src/send.cc | 7 +++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +commit da880344f08b66367f1017eb5963450d5c916e91 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Dec 15 05:21:51 2002 +0000 + + Completed the conversion from hostname() to the new config files. + + lib/canonicalize.cc | 4 +-- + lib/hostname.cc | 70 +++++++++-------------------------------------------- + lib/hostname.h | 7 ++++-- + protocols/smtp.cc | 3 ++- + src/inject.cc | 8 +----- + src/queue.cc | 6 +---- + 6 files changed, 21 insertions(+), 77 deletions(-) + +commit abf914f1e1c9c0f083760a2ac5fc4dc474ebce12 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Dec 15 03:18:09 2002 +0000 + + Fixed a bug in the setenv function in sendmail.cc. + + NEWS | 2 ++ + 1 file changed, 2 insertions(+) + +commit 6d6b72544f4f345a6b811fcb18035eedb848a612 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Sep 22 05:15:29 2001 +0000 + + The parameter for putenv must not be automatic. + + src/sendmail.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 0bfd0e7986ed7eef63c763723a13beb5cb0aac6e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Aug 26 03:49:12 2001 +0000 + + Drop address header fields with blank contents. + + src/inject.cc | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +commit 0eb76674d28ec00176cda2e21e04c8eacf825450 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Aug 26 03:46:23 2001 +0000 + + Completed handling empty address lists. + + lib/address.cc | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit da92f1e915dfceb6502047b3f0388e90987a303f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sun Aug 26 03:15:31 2001 +0000 + + Modified to properly parse an empty address field as empty. + + lib/address.cc | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +commit f9623df6d301f8092e033e1506defa51f9428189 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jul 10 01:39:40 2001 +0000 + + Updated for the new untroubled.org web site. + + makedist.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 432fea67613a7a32218d4ae3b6826b74182c7b67 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jul 10 01:39:18 2001 +0000 + + *** empty log message *** + + NEWS | 7 +++++++ + README | 6 ++++++ + TODO | 21 +++++++++++++++++++-- + 3 files changed, 32 insertions(+), 2 deletions(-) + +commit 853dabd29822cc4b25dd56a652bd028d888e0199 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jul 10 01:38:54 2001 +0000 + + Redirect stderr to stdout before starting anything else to catch error + messages. + + scripts/nullmailer.run | 1 + + 1 file changed, 1 insertion(+) + +commit dbb47f9cecb13595241cd7daeb3bc6af27a930e9 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jul 10 01:38:29 2001 +0000 + + Fixed a quoting bug with handling lines starting with ".". + + protocols/smtp.cc | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +commit f353c7acadf52776286d3ff59406a20513570b90 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jul 10 01:37:33 2001 +0000 + + Tidied up the library function checks. + + configure.in | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit dacc07ea5f76fc94775e60b8e724754647383c97 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jul 10 01:36:59 2001 +0000 + + Added an ignored option entry from the sendmail "-m" option. + + src/sendmail.cc | 1 + + 1 file changed, 1 insertion(+) + +commit efbb131064feceb37660df104c68fd1bf4c525b5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Mar 29 21:57:30 2001 +0000 + + Fixed instructions on RPM startup. + + HOWTO | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6398dc58e24a54ee71115d6f2cabaee8d067646d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Mar 29 21:57:06 2001 +0000 + + *** empty log message *** + + TODO | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +commit b1e425291726b6fa8cc437e06f440991a0fe770d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Mar 29 21:56:36 2001 +0000 + + Removed unnecessary init.d directory, and added in the man7 pages. + + spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit 45dbeb96ea19ca1a64f9edd16ad12e2714772ae8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Feb 27 22:38:05 2001 +0000 + + Fixed some include file problems with sys/time.h. + + NEWS | 4 ++-- + configure.in | 4 ++-- + lib/makefield.cc | 2 +- + src/send.cc | 2 +- + 4 files changed, 6 insertions(+), 6 deletions(-) + +commit 7cdfa39c46ee4b934d7ad21ba7414e38cf135194 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Feb 7 21:45:32 2001 +0000 + + *** empty log message *** + + ChangeLog | 5 +++++ + README | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +commit 29bf85c4dd9fb2f27c27fd94c48df4389c3ba9b8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Feb 7 21:45:13 2001 +0000 + + Modified to always attempt to send everything in the queue. + + src/send.cc | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +commit 74e72decb13a35cad74750daf08a23d2f7c71c85 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Feb 2 02:30:36 2001 +0000 + + Bumped up version number to 1.00RC6. + + ChangeLog | 4 ++++ + NEWS | 11 ++++++++--- + TODO | 5 +++++ + configure.in | 2 +- + 4 files changed, 18 insertions(+), 4 deletions(-) + +commit 4a6ad6d42872d58eaac0604e28c05fd852ee52e3 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Feb 2 02:28:53 2001 +0000 + + Added a missing include. + + lib/hostname.cc | 1 + + src/send.cc | 1 + + 2 files changed, 2 insertions(+) + +commit 29e1d10faada18b867f5ffa0b84abaa38625c189 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Dec 30 10:22:46 2000 +0000 + + Added 1.00RC5 release notes. + + NEWS | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +commit 11a605944d897d9bfb51abcbc5a65af9db673b84 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Dec 30 10:18:42 2000 +0000 + + *** empty log message *** + + makedist.in | 3 ++- + spec | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +commit 841ccae483442aba48ad0d9b8312beea0a4bb5f0 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Dec 30 10:16:46 2000 +0000 + + Make the service directory. + + spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b5a02d72560f8a58149d907408b6d6d55759879e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Dec 30 10:12:45 2000 +0000 + + Bumped up version number. + + README | 4 ++-- + configure.in | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +commit 0a0590220eacca1bb7965d414d2aab2ca26b4675 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Dec 30 09:47:26 2000 +0000 + + Removed unnecessary init script. + + scripts/nullmailer.init | 39 --------------------------------------- + 1 file changed, 39 deletions(-) + delete mode 100644 scripts/nullmailer.init + +commit adad7709bf7490eb355ff5eeede0a1d3b60be3e5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Dec 30 09:47:17 2000 +0000 + + Modified to use supervise-scripts 3. + + spec | 38 +++++++++++++++----------------------- + 1 file changed, 15 insertions(+), 23 deletions(-) + +commit d62e97b74d464bb7863fb755272a7fa33c3b8578 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Dec 30 09:41:21 2000 +0000 + + Return proper error codes for permanent and temporary SMTP failures. + + protocols/smtp.cc | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +commit c6654636d6e2812e371ee1193e815412ea117a20 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Dec 30 09:41:02 2000 +0000 + + Fixed the prototype for getdomainname. + + lib/hostname.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ef0704b64da065036a7193dbfd5141043ac00aad +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Dec 30 09:40:44 2000 +0000 + + *** empty log message *** + + ChangeLog | 9 +++++++++ + HOWTO | 2 +- + 2 files changed, 10 insertions(+), 1 deletion(-) + +commit 3adb189998e0f75e03129a017fbc1d399739303e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Aug 30 20:58:37 2000 +0000 + + Moved extern declaration of getdomainname out of the function. + + lib/hostname.cc | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +commit 5cede356e41da63b71a1efa0d8a5887dbe847a18 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 29 05:11:45 2000 +0000 + + Added missing INSTALL dist file. + + Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 37b555d7173f83a89bdfdb7324a041d8d39c281a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 29 05:11:09 2000 +0000 + + Renamed the script files. + + scripts/{run-log => nullmailer-log.run} | 0 + scripts/{init => nullmailer.init} | 0 + scripts/{run-svc => nullmailer.run} | 0 + spec | 6 +++--- + 4 files changed, 3 insertions(+), 3 deletions(-) + rename scripts/{run-log => nullmailer-log.run} (100%) + rename scripts/{init => nullmailer.init} (100%) + rename scripts/{run-svc => nullmailer.run} (100%) + +commit 195f92e0b52b263cf908701fa929a277eb14ca12 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 29 00:07:50 2000 +0000 + + Fixed up forgotten ChangeLog entries. + + ChangeLog | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 9685b2cccd7befeb33631da041d93544b5425fe7 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 29 00:00:15 2000 +0000 + + Final RC4 update. + + NEWS | 8 +++++--- + README | 2 +- + 2 files changed, 6 insertions(+), 4 deletions(-) + +commit 46994cdeb5a3d6331e9e6a069273677ed5ffb694 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Aug 28 23:58:38 2000 +0000 + + Test addresses with trailing periods. + + test/address-test.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +commit b7deddd27024f40efb9605d8db0e3bba11233377 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Aug 28 23:57:43 2000 +0000 + + Fixed to handle addresses with trailing periods. + + lib/address.cc | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +commit 022a4edce2341a45836c75492f0bf33f45b5e281 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Aug 16 01:28:46 2000 +0000 + + Added extern declaration of getdomainname for systems that don't declare + it. + + lib/hostname.cc | 1 + + 1 file changed, 1 insertion(+) + +commit d13669d5bec5b7d2d451b35429cb72371e4fe876 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Aug 16 01:28:25 2000 +0000 + + *** empty log message *** + + ChangeLog | 5 +++++ + NEWS | 1 + + TODO | 4 ---- + 3 files changed, 6 insertions(+), 4 deletions(-) + +commit 5dd4e7c4559d934c603b7440f56f8b9c65d0c7b1 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Aug 16 01:21:22 2000 +0000 + + Updated install instructions in HOWTO, removed the modified INSTALL + document. + + HOWTO | 22 ++++---- + INSTALL | 184 ---------------------------------------------------------------- + README | 2 +- + TODO | 4 ++ + 4 files changed, 14 insertions(+), 198 deletions(-) + delete mode 100644 INSTALL + +commit d45b24c27720452fd0c7102a1a6e88bfca4a4b7d +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Aug 16 01:13:24 2000 +0000 + + Added custom INSTALL instructions. + + INSTALL | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 184 insertions(+) + create mode 100644 INSTALL + +commit b868ae6ecebc1030a20befbf2619529ed57a775a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 15 22:45:39 2000 +0000 + + Ignore warnings from compile output. + + acinclude.m4 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 88f19c732b2ed6f8fdc91a140b4b1076a0f6ef71 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Mon Aug 14 21:05:51 2000 +0000 + + Fixed the reversed named pipe bug logic. + + NEWS | 6 ++++++ + acinclude.m4 | 3 ++- + configure.in | 2 +- + 3 files changed, 9 insertions(+), 2 deletions(-) + +commit e11b9203bf2b7fb2ae57e6f91d3e72349b700fd8 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Aug 11 11:10:25 2000 +0000 + + 1.00RC3 release checkin. + + ChangeLog | 2 ++ + NEWS | 1 + + README | 4 ++-- + makedist.in | 13 +++++-------- + 4 files changed, 10 insertions(+), 10 deletions(-) + +commit 294e5aa230f8e6557574c4e6417c5435c738822c +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Aug 11 11:09:41 2000 +0000 + + Fixed a problem with multiple use of itoa. + + test/address-test.cc | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +commit 75c881a04cc16ae09c60938fe950c0c0ac9ef560 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Aug 11 00:48:19 2000 +0000 + + Added configure test for named pipe bug. + + ChangeLog | 21 +++++++++++++++++++++ + NEWS | 5 +++++ + TODO | 11 +++++------ + acconfig.h | 2 ++ + acinclude.m4 | 34 ++++++++++++++++++++++++++++++++++ + configure.in | 4 +++- + 6 files changed, 70 insertions(+), 7 deletions(-) + +commit be2db683e5cb28ebd4701c9554650a3ca6eb4681 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Fri Aug 11 00:47:53 2000 +0000 + + Fixed header parsing logic. + + src/inject.cc | 80 ++++++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 49 insertions(+), 31 deletions(-) + +commit 5852e4eb6e687c16f4f242fe957de709e554e3c4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 8 11:09:35 2000 +0000 + + Added code to handle systems that require a writer on the named pipe. + + src/send.cc | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit 7c8ee6dd883babf00442b3082bda73b50cb05c5a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 8 11:08:43 2000 +0000 + + Added a handler for the -L sendmail option (ignored). + + src/sendmail.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit f45ce51c6178a7e4b799781166c70a1a897457e4 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 8 11:08:08 2000 +0000 + + Added man page for the sendmail emulator. + + doc/Makefile.am | 1 + + doc/sendmail.1 | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 76 insertions(+) + create mode 100644 doc/sendmail.1 + +commit c40bd02e6cf8c0a6c3706503ac3f88489f1c0678 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 8 10:43:47 2000 +0000 + + Added an overall man page for nullmailer. + + doc/Makefile.am | 5 +++-- + doc/nullmailer.7 | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 33 insertions(+), 2 deletions(-) + create mode 100644 doc/nullmailer.7 + +commit 914c03a6dbbb4e1052090939ee89b91b9cf44cf2 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 8 10:31:02 2000 +0000 + + Fixed a typo in the root-install chmods. + + Makefile.am | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 169c32515a18966632adc2d23df19c83324f3c61 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Aug 8 10:16:13 2000 +0000 + + Fixed some typos. + + lib/tcpconnect.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 4c0ee03eb407127c4ba741d2240defaeeb95cbc2 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Sat Jul 8 00:21:53 2000 +0000 + + Fixed up release notes. + + ChangeLog | 2 ++ + NEWS | 5 +++++ + TODO | 3 ++- + 3 files changed, 9 insertions(+), 1 deletion(-) + +commit 72e2c21a123deb0636e99f7c140dbb06ce45ecb5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jul 4 09:37:35 2000 +0000 + + Fixed typo in lib/hostname.cc + + ChangeLog | 5 +++++ + lib/hostname.cc | 6 +++--- + 2 files changed, 8 insertions(+), 3 deletions(-) + +commit 9110a039f500dcdb7158f21a8023a569967d541a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jun 28 21:27:46 2000 +0000 + + Added utsname tests to configure. + + ChangeLog | 10 ++++++++++ + NEWS | 9 +++++++++ + acconfig.h | 2 ++ + acinclude.m4 | 27 +++++++++++++++++++++++++++ + configure.in | 3 ++- + 5 files changed, 50 insertions(+), 1 deletion(-) + +commit 7407ffc714f0ae8b7be3e144b26586b241747ec5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jun 28 21:26:44 2000 +0000 + + Fixed domain name determination bug, and portability fix in mergelib.sh + + lib/hostname.cc | 34 ++++++++++++++++++++++++++++------ + lib/mergelib.sh | 2 +- + 2 files changed, 29 insertions(+), 7 deletions(-) + +commit ac5526eb24b95b6f39ee009104da2f2c867913c0 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Wed Jun 28 21:26:05 2000 +0000 + + Fixed response number bug. + + protocols/smtp.cc | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +commit b0e7a7464abe860551226e0870dd3f37f6ddc365 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Tue Jun 20 01:47:50 2000 +0000 + + Fixed a minor type bug. + + ChangeLog | 5 +++++ + lib/tcpconnect.cc | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +commit b9d8016c91144d1986029bc1bb7ad539c251b233 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 15 21:26:49 2000 +0000 + + Final release 1.00RC1 check in. + + ChangeLog | 2 ++ + 1 file changed, 2 insertions(+) + +commit 4a07e155c61694340e6f797b55bbf48a941dbafa +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 15 21:22:13 2000 +0000 + + Final 1.00RC1 check in. + + NEWS | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit fcae2ba8b7bac005c7b0de960663f6e20c37deb6 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 15 21:20:59 2000 +0000 + + Fixed up NEWS and README to reflect new version number. + + NEWS | 2 +- + README | 11 +++++++++++ + configure.in | 2 +- + 3 files changed, 13 insertions(+), 2 deletions(-) + +commit bf50ea12ddf8170cf5d2cc87bfeee4175d2d617f +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 15 21:13:53 2000 +0000 + + Fixed up copyright notices. + + lib/address-old.cc | 21 +++++++++++++++++++++ + lib/address.cc | 21 +++++++++++++++++++++ + lib/canonicalize.cc | 21 +++++++++++++++++++++ + lib/config_read.cc | 21 +++++++++++++++++++++ + lib/config_readint.cc | 21 +++++++++++++++++++++ + lib/config_readlist.cc | 21 +++++++++++++++++++++ + lib/errcodes.cc | 21 +++++++++++++++++++++ + lib/hostname.cc | 21 +++++++++++++++++++++ + lib/makefield.cc | 21 +++++++++++++++++++++ + lib/tcpconnect.cc | 21 +++++++++++++++++++++ + protocols/protocol.cc | 4 ++-- + protocols/qmqp.cc | 21 +++++++++++++++++++++ + protocols/smtp.cc | 21 +++++++++++++++++++++ + src/inject.cc | 21 +++++++++++++++++++++ + src/mailq.cc | 21 +++++++++++++++++++++ + src/queue.cc | 21 +++++++++++++++++++++ + src/send.cc | 21 +++++++++++++++++++++ + src/sendmail.cc | 4 ++-- + 18 files changed, 340 insertions(+), 4 deletions(-) + +commit 81cbaafd9f3054a18c3b47fe43e8300473b2db21 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 15 21:13:42 2000 +0000 + + Added note on bug fix to lib/makefields.cc + + ChangeLog | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit ef8870f75cfb67b2e4745a43ab9cf008fff17165 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 15 20:59:15 2000 +0000 + + Removed compiled binary file address-test. + + test/address-test | Bin 239088 -> 0 bytes + 1 file changed, 0 insertions(+), 0 deletions(-) + delete mode 100644 test/address-test + +commit e4438a9a7ee6c094b0fa7aa3d07a864482f2e5b5 +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 15 20:58:41 2000 +0000 + + Fixed include file paths. + + protocols/Makefile.am | 4 ++-- + protocols/protocol.h | 2 +- + protocols/qmqp.cc | 4 ++-- + protocols/smtp.cc | 4 ++-- + src/inject.cc | 12 ++++++------ + src/mailq.cc | 2 +- + src/queue.cc | 6 +++--- + src/send.cc | 2 +- + src/sendmail.cc | 4 ++-- + test/Makefile.am | 2 +- + test/address-test | Bin 231376 -> 239088 bytes + test/address-test.cc | 4 ++-- + 12 files changed, 23 insertions(+), 23 deletions(-) + +commit 528cc2d62f77e9d5024494e087b06f194b13411e +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 15 20:58:12 2000 +0000 + + Fixed include file paths, added missing shell scripts and removed some + unnecessary headers. + + lib/Makefile.am | 13 ++++++++----- + lib/address.cc | 2 +- + lib/address.h | 2 +- + lib/canonicalize.cc | 4 ++-- + lib/canonicalize.h | 2 +- + lib/config_read.cc | 2 +- + lib/config_readint.cc | 2 +- + lib/config_readlist.cc | 2 +- + lib/configio.h | 2 +- + lib/connect.h | 2 +- + lib/defines.cc | 8 -------- + lib/fdbuf.h | 0 + lib/hostname.cc | 4 ++-- + lib/make_defines.sh | 9 +++++++++ + lib/makefield.cc | 25 ++++++++++--------------- + lib/mergelib.sh | 16 ++++++++++++++++ + lib/mystring.h | 0 + lib/netstring.h | 2 +- + 18 files changed, 56 insertions(+), 41 deletions(-) + delete mode 100644 lib/defines.cc + delete mode 100644 lib/fdbuf.h + create mode 100644 lib/make_defines.sh + create mode 100644 lib/mergelib.sh + delete mode 100644 lib/mystring.h + +commit 2c137077a1f079c8e3073dee5c45faf172391faf +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Jun 15 20:57:32 2000 +0000 + + Bumped the version number, and touched up the README and NEWS. + + NEWS | 6 ++++++ + README | 4 +--- + configure.in | 2 +- + makedist.in | 2 ++ + 4 files changed, 10 insertions(+), 4 deletions(-) + +commit e2dc08d88ac995de9541b544b88e46e393a7079a +Author: Bruce Guenter <bruce@untroubled.org> +Date: Thu Feb 17 00:24:45 2000 +0000 + + Imported sources. + + AUTHORS | 1 + + BUGS | 4 + + ChangeLog | 435 +++++++++++++++++++++++++++++ + HOWTO | 45 +++ + Makefile.am | 28 ++ + NEWS | 143 ++++++++++ + README | 9 + + TODO | 5 + + YEAR2000 | 10 + + acconfig.h | 17 ++ + acinclude.m4 | 71 +++++ + configure.in | 50 ++++ + doc/Makefile.am | 6 + + doc/diagram | 21 ++ + doc/nullmailer-inject.1 | 240 ++++++++++++++++ + doc/nullmailer-queue.8 | 51 ++++ + doc/nullmailer-send.8 | 72 +++++ + lib/Makefile.am | 36 +++ + lib/address-old.cc | 560 ++++++++++++++++++++++++++++++++++++++ + lib/address.cc | 619 ++++++++++++++++++++++++++++++++++++++++++ + lib/address.h | 8 + + lib/canonicalize.cc | 19 ++ + lib/canonicalize.h | 7 + + lib/config_read.cc | 15 + + lib/config_readint.cc | 15 + + lib/config_readlist.cc | 23 ++ + lib/configio.h | 11 + + lib/connect.h | 8 + + lib/defines.cc | 8 + + lib/defines.h | 13 + + lib/errcodes.cc | 24 ++ + lib/errcodes.h | 26 ++ + lib/fdbuf.h | 0 + lib/hostname.cc | 34 +++ + lib/hostname.h | 7 + + lib/itoa.cc | 23 ++ + lib/itoa.h | 11 + + lib/list.h | 196 +++++++++++++ + lib/listtest.cc | 50 ++++ + lib/makefield.cc | 55 ++++ + lib/mystring.h | 0 + lib/netstring.cc | 13 + + lib/netstring.h | 8 + + lib/tcpconnect.cc | 46 ++++ + makedist.in | 42 +++ + protocols/Makefile.am | 11 + + protocols/protocol.cc | 52 ++++ + protocols/protocol.h | 12 + + protocols/qmqp.cc | 113 ++++++++ + protocols/smtp.cc | 118 ++++++++ + scripts/init | 39 +++ + scripts/run-log | 2 + + scripts/run-svc | 2 + + spec | 93 +++++++ + src/Makefile.am | 28 ++ + src/address-main.cc | 21 ++ + src/inject.cc | 542 ++++++++++++++++++++++++++++++++++++ + src/mailq.cc | 38 +++ + src/queue.cc | 179 ++++++++++++ + src/send.cc | 286 +++++++++++++++++++ + src/sendmail.cc | 135 +++++++++ + test/Makefile.am | 24 ++ + test/address-test | Bin 0 -> 231376 bytes + test/address-test.cc | 177 ++++++++++++ + test/address-trace.cc | 2 + + test/functions | 41 +++ + test/tests/inject/bad-headers | 15 + + test/tests/inject/date | 12 + + test/tests/inject/from | 66 +++++ + test/tests/inject/message-id | 24 ++ + test/tests/inject/recips | 50 ++++ + test/tests/inject/return-path | 9 + + test/tests/inject/sender | 76 ++++++ + test/tests/protocols | 44 +++ + test/tests/queue/rewrite | 45 +++ + 75 files changed, 5341 insertions(+) + create mode 100644 AUTHORS + create mode 100644 BUGS + create mode 100644 ChangeLog + create mode 100644 HOWTO + create mode 100644 Makefile.am + create mode 100644 NEWS + create mode 100644 README + create mode 100644 TODO + create mode 100644 YEAR2000 + create mode 100644 acconfig.h + create mode 100644 acinclude.m4 + create mode 100644 configure.in + create mode 100644 doc/Makefile.am + create mode 100644 doc/diagram + create mode 100644 doc/nullmailer-inject.1 + create mode 100644 doc/nullmailer-queue.8 + create mode 100644 doc/nullmailer-send.8 + create mode 100644 lib/Makefile.am + create mode 100644 lib/address-old.cc + create mode 100644 lib/address.cc + create mode 100644 lib/address.h + create mode 100644 lib/canonicalize.cc + create mode 100644 lib/canonicalize.h + create mode 100644 lib/config_read.cc + create mode 100644 lib/config_readint.cc + create mode 100644 lib/config_readlist.cc + create mode 100644 lib/configio.h + create mode 100644 lib/connect.h + create mode 100644 lib/defines.cc + create mode 100644 lib/defines.h + create mode 100644 lib/errcodes.cc + create mode 100644 lib/errcodes.h + create mode 100644 lib/fdbuf.h + create mode 100644 lib/hostname.cc + create mode 100644 lib/hostname.h + create mode 100644 lib/itoa.cc + create mode 100644 lib/itoa.h + create mode 100644 lib/list.h + create mode 100644 lib/listtest.cc + create mode 100644 lib/makefield.cc + create mode 100644 lib/mystring.h + create mode 100644 lib/netstring.cc + create mode 100644 lib/netstring.h + create mode 100644 lib/tcpconnect.cc + create mode 100644 makedist.in + create mode 100644 protocols/Makefile.am + create mode 100644 protocols/protocol.cc + create mode 100644 protocols/protocol.h + create mode 100644 protocols/qmqp.cc + create mode 100644 protocols/smtp.cc + create mode 100644 scripts/init + create mode 100644 scripts/run-log + create mode 100644 scripts/run-svc + create mode 100644 spec + create mode 100644 src/Makefile.am + create mode 100644 src/address-main.cc + create mode 100644 src/inject.cc + create mode 100644 src/mailq.cc + create mode 100644 src/queue.cc + create mode 100644 src/send.cc + create mode 100644 src/sendmail.cc + create mode 100644 test/Makefile.am + create mode 100644 test/address-test + create mode 100644 test/address-test.cc + create mode 100644 test/address-trace.cc + create mode 100644 test/functions + create mode 100644 test/tests/inject/bad-headers + create mode 100644 test/tests/inject/date + create mode 100644 test/tests/inject/from + create mode 100644 test/tests/inject/message-id + create mode 100644 test/tests/inject/recips + create mode 100644 test/tests/inject/return-path + create mode 100644 test/tests/inject/sender + create mode 100644 test/tests/protocols + create mode 100644 test/tests/queue/rewrite @@ -0,0 +1,47 @@ +Configuration of this program in the typical case is quite simple. + +1. Compile and install the program. If you are using the RPM, skip this +step. See the INSTALL file for more details. Note that this package is +designed to execute as a non-privileged user named "nullmail". When you +do the final install, add the "nullmail" user (typically with either a +non-privileged group or a new "nullmail" group) and run "make +install-root" to set up the files with the proper permissions. + +2. Set up your hostname in SYSCONFDIR[1]/nullmailer/me. Usually this + will be as simple as typing: + /bin/hostname >SYSCONFDIR/nullmailer/me + You may also wish to set up the defaultdomain and defaulthost + configuration files. See the man page for nullmailer-inject for more + details. + +3. Into the file SYSCONFDIR/nullmailer/remotes, put one line for each of +your relay hosts (the computer or computers to which you will send all +your mail): + HOSTNAME PROTOCOL +You will have specified the SYSCONFDIR during configuration of the +install step. On most systems, it will be /usr/local/etc. The RPMs use +/etc. HOSTNAME is the fully-qualified host name of the relay host, or +its numerical IP address. PROTOCOL will typically be "smtp" (without +the quotes), but QMQP[2] is also supported with the "qmqp" module. + +4. Start nullmailer-send. If you are using the RPM, ignore the rest of +the instructions and type: + svc-start nullmailer +Otherwise, you will need to set up the appropriate scripts to run +nullmailer-send in the background, with its output going to a logging +program. The following is an appropriate run script for use with +daemontools[3]: + #!/bin/sh + exec setuidgid nullmail nullmailer-send 2>&1 + +5. You're done! The included sendmail emulator front-end should allow +most (if not all) sendmail-compatible programs to run without any +changes. See the man page for nullmailer-inject for details on outgoing +email message header formatting options. + +Footnotes: +1. SYSCONFDIR is the system configuration directory, as configured +during compilation. It defaults to /usr/local/etc +2. QMQP is a high-speed mail queueing protocol, used with qmail. See +http://cr.yp.to/proto/qmqp.html +3. See http://cr.yp.to/daemontools.html. @@ -0,0 +1,20 @@ +To build and install nullmailer, run: + + sh autogen.sh + ./configure + make + sudo make install install-root + +(Running autogen.sh is optional for release packages) + +To enable SSL/TLS support, add "--enable-tls" to the configure command +line above. + +The default installation expects that a user and group "nullmail" have +already been set up. The install steps will create all appropriate +configuration and queue directories, and change their ownership as needed. + +You may set the installation directory and other parameters by options +to ./configure. To see them, run: + + ./configure --help diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..52cd654 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,31 @@ +localstatedir = @localstatedir@/spool/nullmailer +sysconfdir = @sysconfdir@/nullmailer + +EXTRA_DIST = BUGS HOWTO INSTALL TODO spec \ + scripts/nullmailer.run scripts/nullmailer-log.run \ + scripts/nullmailer.service +SUBDIRS = doc lib protocols src test + +install-data-local: + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(localstatedir)/failed + chmod 700 $(DESTDIR)$(localstatedir)/failed + $(mkinstalldirs) $(DESTDIR)$(localstatedir)/queue + chmod 700 $(DESTDIR)$(localstatedir)/queue + $(mkinstalldirs) $(DESTDIR)$(localstatedir)/tmp + chmod 700 $(DESTDIR)$(localstatedir)/tmp + $(mkinstalldirs) $(DESTDIR)$(sysconfdir) + $(RM) -f $(DESTDIR)$(localstatedir)/trigger + mkfifo $(DESTDIR)$(localstatedir)/trigger + chmod 600 $(DESTDIR)$(localstatedir)/trigger + +install-root: + chown nullmail $(DESTDIR)$(localstatedir)/* + chown nullmail $(DESTDIR)$(sbindir)/nullmailer-queue + chmod u+s $(DESTDIR)$(sbindir)/nullmailer-queue + chown nullmail $(DESTDIR)$(bindir)/mailq + chmod u+s $(DESTDIR)$(bindir)/mailq + +dist-hook: + sed -e s/@VERSION\@/@VERSION@/ \ + <$(srcdir)/spec >$(distdir)/nullmailer-@VERSION@.spec diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..245704f --- /dev/null +++ b/Makefile.in @@ -0,0 +1,805 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ + COPYING ChangeLog INSTALL NEWS README TODO compile depcomp \ + install-sh missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HAVE_GETADDRINFO = @HAVE_GETADDRINFO@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RM = @RM@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@/spool/nullmailer +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@/nullmailer +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = BUGS HOWTO INSTALL TODO spec \ + scripts/nullmailer.run scripts/nullmailer-log.run \ + scripts/nullmailer.service + +SUBDIRS = doc lib protocols src test +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-data-local + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ + dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \ + dist-zip distcheck distclean distclean-generic distclean-hdr \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-data-local install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +install-data-local: + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(localstatedir)/failed + chmod 700 $(DESTDIR)$(localstatedir)/failed + $(mkinstalldirs) $(DESTDIR)$(localstatedir)/queue + chmod 700 $(DESTDIR)$(localstatedir)/queue + $(mkinstalldirs) $(DESTDIR)$(localstatedir)/tmp + chmod 700 $(DESTDIR)$(localstatedir)/tmp + $(mkinstalldirs) $(DESTDIR)$(sysconfdir) + $(RM) -f $(DESTDIR)$(localstatedir)/trigger + mkfifo $(DESTDIR)$(localstatedir)/trigger + chmod 600 $(DESTDIR)$(localstatedir)/trigger + +install-root: + chown nullmail $(DESTDIR)$(localstatedir)/* + chown nullmail $(DESTDIR)$(sbindir)/nullmailer-queue + chmod u+s $(DESTDIR)$(sbindir)/nullmailer-queue + chown nullmail $(DESTDIR)$(bindir)/mailq + chmod u+s $(DESTDIR)$(bindir)/mailq + +dist-hook: + sed -e s/@VERSION\@/@VERSION@/ \ + <$(srcdir)/spec >$(distdir)/nullmailer-@VERSION@.spec + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: @@ -0,0 +1,424 @@ +This file lists all the major user-visible changes to nullmailer. +------------------------------------------------------------------------------- +Changes in version 2.1 + +- Added support for TLS anonymous authentication. + Thanks Uffe Jakobsen. + +- Fixed sendmail wrapper handling of empty sender on command line. + Thanks Sebastian Wiedenroth. + +- Fixed handling of quoted strings in the "remotes" file. + Thanks Mihai Moldovan. + +- Fixed nullmailer-inject handling of leading "From " lines. + +- Some build fixes. + +- Fixed bogus temporary gethostbyname error message when the protocol + source address was incorrect. + +- Fixed potential race condition in tests. + Thanks Felix Lechner. + +- Fixed handling of time values on 32-bit big-endian systems. + Thanks Felix Lechner. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 2.0 + +- Added support to nullmailer-send to move permanently failing messages + out of the queue, and to generate bounce messages. + +- Added support for IPv6. + +- Added program to generate bounce/delay messages. + +- Added an "allmailfrom" control file to nullmailer-queue, causing all + messages to share a hard-coded envelope sender. + +- Added logging the message sender/recipient in nullmailer-send. + +- Improved handling of system errors when reading config files. + +- Secured handling of password options for protocol modules. + +- Support standard shell quoting for options in the "remotes" file. + +- Added protocol option to set a separate TLS client private key file. + +- Added protocol option to bind the source address on connections. + +- Fixed nullmailer-inject to report errors to stderr. + +- Fixed gnutls cast to pointer from integer of different size warning. + +- Fixed nullmailer-inject and -queue to handle the null (empty) sender + address. Needed for RFC 3798 (Message Disposition Notification). + +- Moved spool directory to /var/spool/nullmailer like other MTAs. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.13 + +- Fixed growing recipient list when using sendmail -bs to send multiple + messages. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.12 + +- Added a quadratic backoff for resend times. + +- Added support for multiple admin addresses in nullmailer-queue. + +- SMTP sender now sends a QUIT on success too. + +- Fixed sendmail -bs mode to properly strip leading periods. + +- Fixed duplicated final header line when message has no body. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.11 + +- Simplify (and expand) handling of ignored sendmail options. + +- Fixed command-line interpretation of short options with values. + +- Added support for SSL/TLS client certificates. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.10 + +- Added support for SMTPS (SMTP over SSL/TLS) and STARTTLS. + +- Added support for auto-detection of login method in SMTP protocol. + +- Added support for -bp (mailq) and -bs (SMTP) mode in the sendmail wrapper. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.06 + +- Made nullmailer-queue sync and not just flush queued files to protect + against crashes during sensitive operations. + +- Fixed handling of whitespace in quoted strings in headers. + +- Fixed handling of timeouts when sending. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.05 + +- Fixed compilation of src/selfpipe.cc on Solaris and other OSes. + +- Fixed handling of TM_HAS_ISDST on Solaris. + +- Fixed a few address parsing glitches. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.04 + +- Fixed rewriting mail to @localhost if defaultdomain is set by not + appending .defaultdomain to *@localhost. + +- Added support for reporting the sender and recipients in mailq. + +- Added a send timeout in nullmailer-send, to kill sending messages that + stall. + +- Added support in nullmailer-inject for $NULLMAILER_QUEUE to name the + program which is used to queue messages. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.03 + +- Fixed the SMTP protocol module to send QUIT on protocol failures. + +- Added support for the SMTP AUTH LOGIN method. Thanks to Sean + MacLennan for the suggestion. + +- Fixed the SMTP protocol module to send EHLO instead of HELO when doing + authentication. Thanks to Norbert Tretkowski for pointing this out. + +- Fixed compile breakage on Solaris due to use of setenv. + +- Fixed netstring length bug in QMQP sending module. + +- If the sender name cannot be determined from the environment + variables, try to pull it from /etc/passwd before using "unknown". + Thanks Roderick Schertler. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.02 + +- Fixed bug in SMTP AUTH that would cause SMTP sending to crash with a + segfault when it was used. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.01 + +- Added support for SMTP AUTH PLAIN. + Thanks to Ace Jones for the initial implementation. + +- Fixed compile error in lib/list.h + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.00 + +- Fixed problem with multiple arguments to protocol modules. + Thanks Sascha Silbe. + +- Fixed extraneous spaces in SMTP sender. + +- Made permissions on queued files more strict. + +- Handle the "-bs" flag in the sendmail wrapper by dieing when we see it. + +- Fixed the address parser handling domain names with trailing periods. + +- Fixed bug in header parsing that would cause the last header line to + be repeated if there was no body. + +- Fixed bug in handling headers containing CR+LF line endings. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.00RC7 + +- Fixed typo in smtp protocol module that caused HELO to be sent without + a hostname. + +- Added a one-shot mode to nullmailer-send, triggered by setting the + pausetime to zero. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.00RC6 + +- Protocol modules now report all failure and success messages. + +- Removed the whole gethostname/getdomainname mess and replaced it with + code to read the hostname from the "me" control file, and the default + domain name from the "defaultdomain" control file. + +- Fixed a bug that would cause lines starting with a period to have that + period stripped when it was sent via SMTP. + +- Added some missing includes to fix compilation failures in various + sources. + +- Fixed a bug in the setenv function in sendmail.cc. + +NOTE! Make sure to set up the new "me" control file before using this +version. The RPM install does this automatically. + +Development of this version has been sponsored by FutureQuest, Inc. +ossi@FutureQuest.net http://www.FutureQuest.net/ +------------------------------------------------------------------------------- +Changes in version 1.00RC5 + +- Fixed getdomainname prototype in lib/hostname.cc. +- Return proper error codes for permanent and temporary SMTP failures. +- Adapted to use supervise-scripts 3. +------------------------------------------------------------------------------- +Changes in version 1.00RC4 + +- Fixed the reversed logic in the named pipe bug check. +- Updated the HOWTO notes. +- Fixed a compile problem on Solaris (and possibly other systems). +- Fixed address parsing to strip a trailing period in the domain name. +------------------------------------------------------------------------------- +Changes in version 1.00RC3 + +- Treat the first non-header line in a message as the first line of the + body, even if it isn't preceded by a blank line. +- Fixed another host name bug causing compilation failures on systems + without "domainname" in struct utsname. +- Fixed some typos that would prevent proper TCP connections on many + systems. +- Handle systems that require both a reader and a writer on a named pipe + to do a proper select. +- Added a man page for the sendmail emulator, and an overall man page. +- Fixed a bug in the fdbuf library that was causing data loss or damage. +------------------------------------------------------------------------------- +Changes in version 1.00RC2 + +- Fixed a bug in the way host names are determined. This should fix + problems with nullmailer-queue reporting an invalid envelope. + +- Fixed a portability bug in the mergelib.sh script. + +- Fixed a potential bug in the SMTP protocol response handling. +------------------------------------------------------------------------------- +Changes in version 1.00RC1 + +- Imported latest fdbuf, mystring, and cli libraries. + +- Fixed a bug in the timezone handling on systems with tm_gmtoff. +------------------------------------------------------------------------------- +Changes in version 0.40 + +- Fixed some compile problems to allow nullmailer to compile on FreeBSD. + +- Fixed a bug in the sendmail emulator to allow it to set the sender + name and address from the command line properly. + +- Modified the CLI library to behave more like the standard getopt + library. + +- Made a change to protocol between nullmailer-send and protocol + modules. nullmailer-send now opens up the message files and passes + them to the protocol module as FD 0 instead of passing a filename. + +- Added some notes to the nullmailer-send manual page explaining how + messages are delivered. +------------------------------------------------------------------------------- +Changes in version 0.39 + +- Fixed problems in nullmailer-send in parsing the "remotes" file. It + previously did not handle comment lines or tabs or multiple white + space. + +- Made nullmailer-inject stricter about header lines to ensure that they + comply with RFC822. + +- Several minor updates to the libraries to bring them up to date. +------------------------------------------------------------------------------- +Changes in version 0.38 + +- Fixed bug in nullmailer-send that caused it to refuse to send mail + when the optional "pausetime" configuration file did not exist. +------------------------------------------------------------------------------- +Changes in version 0.37 + +- Fixed bug in address parser that caused strings like "<a@b.c>" + (without a leading comment) to fail. + +- Make nullmailer-send rescan the mail queue each time it wakes up, + rather than only if the timestamp changes to avoids race conditions. + +- Make nullmailer-send reload its config files ("remotes" and + "pausetime" each time it scans the queue). + +- Fixed top-level install-root target to run chmod/chown on the right + path to nullmailer-queue. + +- Added a configure test for libinet, libsocket, and libxnet libraries + for systems that have their networking code separate from the main C + library (such as Solaris). +------------------------------------------------------------------------------- +Changes in version 0.36 + +- Imported generic CLI library, to avoid the use of getopt on systems + that don't have one. +------------------------------------------------------------------------------- +Changes in version 0.35 + +- Protocols now take a "-p #" to specify the port number to connect to. + +- This option can be specified in the "remotes" file immediately after + the protocol name. + +- nullmailer-send will now only rescan the mail queue if its timestamp + has changed since the last scan. + +- Fixed an observed problem with empty domain names by using uname(2) + instead of domainname and hostname. + +- The header address parsing code is rewritten to do a lexical + tokenization before parsing. + +- Imported new fdbuf and mystring libraries + +- Updated init scripts and RPM spec to work with new daemontools 0.61 + and supervise-scripts packages. +------------------------------------------------------------------------------- +Changes in version 0.33 +- fixed a bug in the "list" template class that caused nullmailer-send + to only send out one message before sleeping +- added a trivial address remapping facility to nullmailer-queue to + allow local addresses to be redirected to a remote administrator + address. +------------------------------------------------------------------------------- +Changes in version 0.32 +- the address parser now deals properly with quoted addresses +------------------------------------------------------------------------------- +Changes in version 0.31 +- added a HOWTO document +- "make install-root" will now properly make nullmailer-queue setuid + nullmail +------------------------------------------------------------------------------- +Changes in version 0.30 +- fixed bug in the I/O library that caused nullmailer-inject to return + an error on messages with a single blank line following the header, + even though the message was successfully sent to nullmailer-queue +- in nullmailer-inject, the hostname of the sender is set from the + defaulthost config file instead of hostname() (note that default is + set from hostname() if the file does not exist) +- fixed a bug in nullmailer-inject that would cause it to incorrectly + clear its recipient list when using command-line recipients with a + "resent" message +------------------------------------------------------------------------------- +Changes in version 0.29 +- included the testing framework (mostly empty) into the package +- fixed some bugs in nullmailer-inject caused by incorrect offsets into + the array of header fields +- many bug fixes to the address parsing framework +- nullmailer-inject now has an option to only print out the message + instead of passing it on to nullmailer-queue +- many sendmail flags are now ignored instead of causing errors in the + sendmail front end to nullmailer-inject +------------------------------------------------------------------------------- +Changes in version 0.28 +- fixed the bugs in the spec and init script +- nullmailer-inject now handles the "c" flag like qmail-inject +- changed some error messages +- the sendmail front end should have its header vs command-line + recipients logic fixed now +------------------------------------------------------------------------------- +Changes in version 0.27 +- added a QMQP protocol module +- fixed a missing NUL-termination when creating the Date header line +- nullmailer-inject now parses the NULLMAILER_FLAGS -- see the man page +------------------------------------------------------------------------------- +Changes in version 0.26 +- nullmailer-queue and nullmailer-send now go into sbin instead of bin +- bugfixes to the unique number generation routines +- moved some files around internally +------------------------------------------------------------------------------- +Changes in version 0.25 +- nullmailer-send now reads a protocol name along with the remote host +- nullmailer-inject now handles its command-line options properly, as + well as reading and using defaulthost, defaultdomain, and idhost +- fixed several bugs in the address parsing and date-generation code +- revised the interface between nullmailer-send and the protocol modules + to simplify the interface and nullmailer-send +------------------------------------------------------------------------------- +Changes in version 0.22 +- added simple sendmail front end +------------------------------------------------------------------------------- @@ -0,0 +1,23 @@ +nullmailer +Simple relay-only mail transport agent +Bruce Guenter <bruce@untroubled.org> +Version 2.1 +2017-10-25 + +This is nullmailer, a sendmail/qmail/etc replacement MTA for hosts which +relay to a fixed set of smart relays. It is designed to be simple to +configure, secure, and easily extendable. + +A mailing list has been set up to discuss this package. To subscribe, +send an email to: + nullmailer-subscribe@lists.untroubled.org +A mailing list archive is available at: + http://lists.untroubled.org/?list=nullmailer + +Development versions of @PACKAGE@ are available at GitHub: + https://github.com/bruceg/nullmailer + +This package is Copyright(C) 2017 Bruce Guenter, and may be copied +according to the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 or a later +version. A copy of this license is included with this package. This +package comes with no warranty of any kind. @@ -0,0 +1,21 @@ +- Convert all proto modules to use timedout reads. + +- Add patterns to the remotes file, to allow messages to be delivered to + different remotes based on the sender or recipient addresses + +- Remove "adminaddr" facility from -queue, and add a more general + destination address rewriting facility to -inject: + - Read a list containing "PATTERN:ADDRESS" lines. + - PATTERN can be a literal "user@FQDN" or just "user", in which case + it must be matched exactly (before qualification). + - PATTERN can be "@FQDN" which matches any user. + +- Generate DDNs for messages older than a configurable time. + +- For version 3: three-state queueing? + - Queue message partially (tmp -> holding) + - Send to smarthost immediately + - Remove from holding if sending succeeds + - Complete queueing (holding -> queue) if sending is deferred + - Return with an error if sending fails (permanently) + - Move all from holding -> queue on startup of nullmailer-send diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..1ef6153 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,125 @@ +dnl TRY_CXX_FLAG(FLAG,[ACTION-IF-FOUND[,ACTION-IF-NOT-FOUND]]) +AC_DEFUN([TRY_CXX_FLAG], +[echo >conftest.cc +if ${CXX-g++} ${CXXFLAGS} -c [$1] conftest.cc >/dev/null 2>&1; then + ifelse([$2], , :, [rm -f conftest* + $2]) +else + ifelse([$3], , :, [rm -f conftest* + $3]) +fi +rm -f conftest*]) + +AC_DEFUN([CXX_NO_RTTI], +[AC_CACHE_CHECK(whether ${CXX-g++} accepts -fno-rtti, + local_cv_flag_NO_RTTI, + TRY_CXX_FLAG(-fno-rtti, + local_cv_flag_NO_RTTI=yes, + local_cv_flag_NO_RTTI=no)) +test "$local_cv_flag_NO_RTTI" = yes && CXXFLAGS="$CXXFLAGS -fno-rtti" +]) + +AC_DEFUN([CXX_NO_EXCEPTIONS], +[AC_CACHE_CHECK(whether ${CXX-g++} accepts -fno-exceptions, + local_cv_flag_NO_EXCEPTIONS, + TRY_CXX_FLAG(-fno-exceptions, + local_cv_flag_NO_EXCEPTIONS=yes, + local_cv_flag_NO_EXCEPTIONS=no)) +test "$local_cv_flag_NO_EXCEPTIONS" = yes && CXXFLAGS="$CXXFLAGS -fno-exceptions" +]) + +dnl TRY_STRUCT_TM_MEMBER(MEMBER,FLAGNAME) +AC_DEFUN([TRY_STRUCT_TM_MEMBER], +[ AC_CACHE_CHECK(whether struct tm contains [$1], + [$2], + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif +int main() { struct tm* foo; foo->[$1]; } +])], + [$2]=yes, + [$2]=no)) +]) + +AC_DEFUN([TEST_STRUCT_TM],[ + TRY_STRUCT_TM_MEMBER(tm_isdst, local_cv_flag_TM_HAS_ISDST) + TRY_STRUCT_TM_MEMBER(__tm_isdst, local_cv_flag_TM_HAS___ISDST) + if test "$local_cv_flag_TM_HAS_ISDST" = yes + then AC_DEFINE(TM_HAS_ISDST,tm_isdst,[struct tm has tm_isdst member]) + elif test "$local_cv_flag_TM_HAS___ISDST" = yes + then AC_DEFINE(TM_HAS_ISDST,__tm_isdst,[struct tm has tm_isdst member]) + fi + TRY_STRUCT_TM_MEMBER(tm_gmtoff, local_cv_flag_TM_HAS_GMTOFF) + TRY_STRUCT_TM_MEMBER(__tm_gmtoff, local_cv_flag_TM_HAS___GMTOFF) + if test "$local_cv_flag_TM_HAS_GMTOFF" = yes + then AC_DEFINE(TM_HAS_GMTOFF,tm_gmtoff,[struct tm has tm_gmtoff member]) + elif test "$local_cv_flag_TM_HAS___GMTOFF" = yes + then AC_DEFINE(TM_HAS_GMTOFF,__tm_gmtoff,[struct tm has tm_gmtoff member]) + fi +]) + +dnl TRY_STRUCT_UTSNAME_MEMBER(MEMBER,FLAGNAME) +AC_DEFUN([TRY_STRUCT_UTSNAME_MEMBER], +[ AC_CACHE_CHECK(whether struct utsname contains [$1], + [$2], + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +#include <sys/utsname.h> +int main() { struct utsname* foo; foo->[$1]; } +])], + [$2]=yes, + [$2]=no)) +]) + +AC_DEFUN([TEST_STRUCT_UTSNAME],[ + TRY_STRUCT_UTSNAME_MEMBER(domainname, local_cv_flag_UTSNAME_HAS_DOMAINNAME) + TRY_STRUCT_UTSNAME_MEMBER(__domainname, + local_cv_flag_UTSNAME_HAS___DOMAINNAME) + if test "$local_cv_flag_UTSNAME_HAS_DOMAINNAME" = yes + then AC_DEFINE(UTSNAME_HAS_DOMAINNAME,domainname,[struct utsname has domainname member]) + elif test "$local_cv_flag_UTSNAME_HAS___DOMAINNAME" = yes + then AC_DEFINE(UTSNAME_HAS_DOMAINNAME,__domainname,[struct utsname has domainname member]) + fi +]) + +AC_DEFUN([CHECK_NAMED_PIPE_BUG], +[ AC_CACHE_CHECK(whether named pipes are buggy, + local_cv_flag_NAMEDPIPEBUG, + cat >conftest.c <<EOF +#include <fcntl.h> +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> +int main(int argc, char** argv) +{ + struct timeval tv; + fd_set rfds; + int fd = open(*(argv+1), O_RDONLY | O_NONBLOCK); + FD_ZERO(&rfds); + FD_SET(fd,&rfds); + tv.tv_sec = tv.tv_usec = 0; + return (select(fd+1, &rfds, 0, 0,&tv) > 0) ? 0 : 1; +} +EOF + if ! ${CC} ${CFLAGS} conftest.c -o conftest 2>/dev/null + then + echo Compile failed + exit 1 + fi + mkfifo conftest.pipe + if ./conftest conftest.pipe + then + AC_DEFINE(NAMEDPIPEBUG, 1, [Named pipes have read/write bug]) + local_cv_flag_NAMEDPIPEBUG=yes + else + local_cv_flag_NAMEDPIPEBUG=no + fi + rm -f conftest*) +]) diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..322b108 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1182 @@ +# generated automatically by aclocal 1.15 -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# -*- Autoconf -*- +# Obsolete and "removed" macros, that must however still report explicit +# error messages when used, to smooth transition. +# +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +AC_DEFUN([AM_CONFIG_HEADER], +[AC_DIAGNOSE([obsolete], +['$0': this macro is obsolete. +You should use the 'AC][_CONFIG_HEADERS' macro instead.])dnl +AC_CONFIG_HEADERS($@)]) + +AC_DEFUN([AM_PROG_CC_STDC], +[AC_PROG_CC +am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc +AC_DIAGNOSE([obsolete], +['$0': this macro is obsolete. +You should simply use the 'AC][_PROG_CC' macro instead. +Also, your code should no longer depend upon 'am_cv_prog_cc_stdc', +but upon 'ac_cv_prog_cc_stdc'.])]) + +AC_DEFUN([AM_C_PROTOTYPES], + [AC_FATAL([automatic de-ANSI-fication support has been removed])]) +AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + AM_RUN_LOG([cat conftest.dir/file]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([acinclude.m4]) @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Written by Tom Tromey <tromey@cygnus.com>. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..7827a2e --- /dev/null +++ b/config.h.in @@ -0,0 +1,135 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Generic buffer size */ +#undef BUFSIZE + +/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* getaddrinfo code enabled */ +#undef HAVE_GETADDRINFO + +/* libgnutls has gnutls_priority_set_direct */ +#undef HAVE_GNUTLS_PRIORITY_SET_DIRECT + +/* libgnutls has gnutls_certificate_set_verify_function */ +#undef HAVE_GNUTLS_SET_VERIFY_FUNCTION + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `inet' library (-linet). */ +#undef HAVE_LIBINET + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the `xnet' library (-lxnet). */ +#undef HAVE_LIBXNET + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the `setenv' function. */ +#undef HAVE_SETENV + +/* Define to 1 if you have the `srandom' function. */ +#undef HAVE_SRANDOM + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Build in support for TLS */ +#undef HAVE_TLS + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Named pipes have read/write bug */ +#undef NAMEDPIPEBUG + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ +#undef TIME_WITH_SYS_TIME + +/* struct tm has tm_gmtoff member */ +#undef TM_HAS_GMTOFF + +/* struct tm has tm_isdst member */ +#undef TM_HAS_ISDST + +/* struct utsname has domainname member */ +#undef UTSNAME_HAS_DOMAINNAME + +/* Version number of package */ +#undef VERSION + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t diff --git a/configure b/configure new file mode 100755 index 0000000..db0766f --- /dev/null +++ b/configure @@ -0,0 +1,7459 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for nullmailer 2.1. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='nullmailer' +PACKAGE_TARNAME='nullmailer' +PACKAGE_VERSION='2.1' +PACKAGE_STRING='nullmailer 2.1' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_unique_file="lib/defines.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +TLS_FALSE +TLS_TRUE +FDBUF_NO_MYSTRING_FALSE +FDBUF_NO_MYSTRING_TRUE +HAVE_GETADDRINFO +EGREP +GREP +CXXCPP +MKDIR +RM +RANLIB +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_dependency_tracking +enable_largefile +enable_tls +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures nullmailer 2.1 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/nullmailer] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of nullmailer 2.1:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --disable-largefile omit support for large files + --enable-tls Enable SSL/TLS support + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +nullmailer configure 2.1 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_run LINENO +# ------------------------ +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_cxx_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_run + +# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_cxx_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_mongrel + +# ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_cxx_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_compile + +# ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES +# --------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_cxx_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_type + +# ac_fn_cxx_check_func LINENO FUNC VAR +# ------------------------------------ +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_cxx_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by nullmailer $as_me 2.1, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +am__api_version='1.15' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='nullmailer' + VERSION='2.1' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +ac_config_headers="$ac_config_headers config.h" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -fno-rtti" >&5 +$as_echo_n "checking whether ${CXX-g++} accepts -fno-rtti... " >&6; } +if ${local_cv_flag_NO_RTTI+:} false; then : + $as_echo_n "(cached) " >&6 +else + echo >conftest.cc +if ${CXX-g++} ${CXXFLAGS} -c -fno-rtti conftest.cc >/dev/null 2>&1; then + rm -f conftest* + local_cv_flag_NO_RTTI=yes +else + rm -f conftest* + local_cv_flag_NO_RTTI=no +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $local_cv_flag_NO_RTTI" >&5 +$as_echo "$local_cv_flag_NO_RTTI" >&6; } +test "$local_cv_flag_NO_RTTI" = yes && CXXFLAGS="$CXXFLAGS -fno-rtti" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX-g++} accepts -fno-exceptions" >&5 +$as_echo_n "checking whether ${CXX-g++} accepts -fno-exceptions... " >&6; } +if ${local_cv_flag_NO_EXCEPTIONS+:} false; then : + $as_echo_n "(cached) " >&6 +else + echo >conftest.cc +if ${CXX-g++} ${CXXFLAGS} -c -fno-exceptions conftest.cc >/dev/null 2>&1; then + rm -f conftest* + local_cv_flag_NO_EXCEPTIONS=yes +else + rm -f conftest* + local_cv_flag_NO_EXCEPTIONS=no +fi +rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $local_cv_flag_NO_EXCEPTIONS" >&5 +$as_echo "$local_cv_flag_NO_EXCEPTIONS" >&6; } +test "$local_cv_flag_NO_EXCEPTIONS" = yes && CXXFLAGS="$CXXFLAGS -fno-exceptions" + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_cxx_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi + + +fi + + +CFLAGS="$CFLAGS -W -Wall" +CXXFLAGS="$CXXFLAGS -W -Wall" + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +# Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $STRIP in + [\\/]* | ?:[\\/]*) + ac_cv_path_STRIP="$STRIP" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_STRIP="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +STRIP=$ac_cv_path_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_RM+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $RM in + [\\/]* | ?:[\\/]*) + ac_cv_path_RM="$RM" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +RM=$ac_cv_path_RM +if test -n "$RM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RM" >&5 +$as_echo "$RM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "mkdir", so it can be a program name with args. +set dummy mkdir; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MKDIR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MKDIR in + [\\/]* | ?:[\\/]*) + ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MKDIR="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MKDIR=$ac_cv_path_MKDIR +if test -n "$MKDIR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5 +$as_echo "$MKDIR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lxnet" >&5 +$as_echo_n "checking for socket in -lxnet... " >&6; } +if ${ac_cv_lib_xnet_socket+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lxnet $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_xnet_socket=yes +else + ac_cv_lib_xnet_socket=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_socket" >&5 +$as_echo "$ac_cv_lib_xnet_socket" >&6; } +if test "x$ac_cv_lib_xnet_socket" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBXNET 1 +_ACEOF + + LIBS="-lxnet $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -linet" >&5 +$as_echo_n "checking for socket in -linet... " >&6; } +if ${ac_cv_lib_inet_socket+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-linet $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_inet_socket=yes +else + ac_cv_lib_inet_socket=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_socket" >&5 +$as_echo "$ac_cv_lib_inet_socket" >&6; } +if test "x$ac_cv_lib_inet_socket" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBINET 1 +_ACEOF + + LIBS="-linet $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 +$as_echo_n "checking for socket in -lsocket... " >&6; } +if ${ac_cv_lib_socket_socket+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_socket_socket=yes +else + ac_cv_lib_socket_socket=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 +$as_echo "$ac_cv_lib_socket_socket" >&6; } +if test "x$ac_cv_lib_socket_socket" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } +if eval \${$as_ac_Header+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval "$as_ac_Header=yes" +else + eval "$as_ac_Header=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$as_ac_Header + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_cxx_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 +$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } +if ${ac_cv_header_sys_wait_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <sys/wait.h> +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_header_sys_wait_h=yes +else + ac_cv_header_sys_wait_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 +$as_echo "$ac_cv_header_sys_wait_h" >&6; } +if test $ac_cv_header_sys_wait_h = yes; then + +$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/time.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm contains tm_isdst" >&5 +$as_echo_n "checking whether struct tm contains tm_isdst... " >&6; } +if ${local_cv_flag_TM_HAS_ISDST+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif +int main() { struct tm* foo; foo->tm_isdst; } + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + local_cv_flag_TM_HAS_ISDST=yes +else + local_cv_flag_TM_HAS_ISDST=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $local_cv_flag_TM_HAS_ISDST" >&5 +$as_echo "$local_cv_flag_TM_HAS_ISDST" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm contains __tm_isdst" >&5 +$as_echo_n "checking whether struct tm contains __tm_isdst... " >&6; } +if ${local_cv_flag_TM_HAS___ISDST+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif +int main() { struct tm* foo; foo->__tm_isdst; } + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + local_cv_flag_TM_HAS___ISDST=yes +else + local_cv_flag_TM_HAS___ISDST=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $local_cv_flag_TM_HAS___ISDST" >&5 +$as_echo "$local_cv_flag_TM_HAS___ISDST" >&6; } + + if test "$local_cv_flag_TM_HAS_ISDST" = yes + then +$as_echo "#define TM_HAS_ISDST tm_isdst" >>confdefs.h + + elif test "$local_cv_flag_TM_HAS___ISDST" = yes + then +$as_echo "#define TM_HAS_ISDST __tm_isdst" >>confdefs.h + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm contains tm_gmtoff" >&5 +$as_echo_n "checking whether struct tm contains tm_gmtoff... " >&6; } +if ${local_cv_flag_TM_HAS_GMTOFF+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif +int main() { struct tm* foo; foo->tm_gmtoff; } + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + local_cv_flag_TM_HAS_GMTOFF=yes +else + local_cv_flag_TM_HAS_GMTOFF=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $local_cv_flag_TM_HAS_GMTOFF" >&5 +$as_echo "$local_cv_flag_TM_HAS_GMTOFF" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm contains __tm_gmtoff" >&5 +$as_echo_n "checking whether struct tm contains __tm_gmtoff... " >&6; } +if ${local_cv_flag_TM_HAS___GMTOFF+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif +int main() { struct tm* foo; foo->__tm_gmtoff; } + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + local_cv_flag_TM_HAS___GMTOFF=yes +else + local_cv_flag_TM_HAS___GMTOFF=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $local_cv_flag_TM_HAS___GMTOFF" >&5 +$as_echo "$local_cv_flag_TM_HAS___GMTOFF" >&6; } + + if test "$local_cv_flag_TM_HAS_GMTOFF" = yes + then +$as_echo "#define TM_HAS_GMTOFF tm_gmtoff" >>confdefs.h + + elif test "$local_cv_flag_TM_HAS___GMTOFF" = yes + then +$as_echo "#define TM_HAS_GMTOFF __tm_gmtoff" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct utsname contains domainname" >&5 +$as_echo_n "checking whether struct utsname contains domainname... " >&6; } +if ${local_cv_flag_UTSNAME_HAS_DOMAINNAME+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/utsname.h> +int main() { struct utsname* foo; foo->domainname; } + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + local_cv_flag_UTSNAME_HAS_DOMAINNAME=yes +else + local_cv_flag_UTSNAME_HAS_DOMAINNAME=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $local_cv_flag_UTSNAME_HAS_DOMAINNAME" >&5 +$as_echo "$local_cv_flag_UTSNAME_HAS_DOMAINNAME" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct utsname contains __domainname" >&5 +$as_echo_n "checking whether struct utsname contains __domainname... " >&6; } +if ${local_cv_flag_UTSNAME_HAS___DOMAINNAME+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/utsname.h> +int main() { struct utsname* foo; foo->__domainname; } + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + local_cv_flag_UTSNAME_HAS___DOMAINNAME=yes +else + local_cv_flag_UTSNAME_HAS___DOMAINNAME=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $local_cv_flag_UTSNAME_HAS___DOMAINNAME" >&5 +$as_echo "$local_cv_flag_UTSNAME_HAS___DOMAINNAME" >&6; } + + if test "$local_cv_flag_UTSNAME_HAS_DOMAINNAME" = yes + then +$as_echo "#define UTSNAME_HAS_DOMAINNAME domainname" >>confdefs.h + + elif test "$local_cv_flag_UTSNAME_HAS___DOMAINNAME" = yes + then +$as_echo "#define UTSNAME_HAS_DOMAINNAME __domainname" >>confdefs.h + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether named pipes are buggy" >&5 +$as_echo_n "checking whether named pipes are buggy... " >&6; } +if ${local_cv_flag_NAMEDPIPEBUG+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.c <<EOF +#include <fcntl.h> +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> +int main(int argc, char** argv) +{ + struct timeval tv; + fd_set rfds; + int fd = open(*(argv+1), O_RDONLY | O_NONBLOCK); + FD_ZERO(&rfds); + FD_SET(fd,&rfds); + tv.tv_sec = tv.tv_usec = 0; + return (select(fd+1, &rfds, 0, 0,&tv) > 0) ? 0 : 1; +} +EOF + if ! ${CC} ${CFLAGS} conftest.c -o conftest 2>/dev/null + then + echo Compile failed + exit 1 + fi + mkfifo conftest.pipe + if ./conftest conftest.pipe + then + +$as_echo "#define NAMEDPIPEBUG 1" >>confdefs.h + + local_cv_flag_NAMEDPIPEBUG=yes + else + local_cv_flag_NAMEDPIPEBUG=no + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $local_cv_flag_NAMEDPIPEBUG" >&5 +$as_echo "$local_cv_flag_NAMEDPIPEBUG" >&6; } + + +for ac_func in setenv srandom +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo" >&5 +$as_echo_n "checking for getaddrinfo... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stddef.h> + +int +main () +{ + +getaddrinfo(NULL, NULL, NULL, NULL) + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + has_getaddrinfo=yes +else + has_getaddrinfo=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +if test "$has_getaddrinfo" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_GETADDRINFO /**/" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled: getaddrinfo missing" >&5 +$as_echo "disabled: getaddrinfo missing" >&6; } +fi + + + +$as_echo "#define BUFSIZE 4096" >>confdefs.h + + if false; then + FDBUF_NO_MYSTRING_TRUE= + FDBUF_NO_MYSTRING_FALSE='#' +else + FDBUF_NO_MYSTRING_TRUE='#' + FDBUF_NO_MYSTRING_FALSE= +fi + + +# Check whether --enable-tls was given. +if test "${enable_tls+set}" = set; then : + enableval=$enable_tls; case "${enableval}" in + yes) tls=true; +$as_echo "#define HAVE_TLS 1" >>confdefs.h + ;; + no) tls=false ;; + *) as_fn_error $? "bad value ${enableval} for --enable-tls" "$LINENO" 5 ;; + esac +else + tls=false +fi + + if $tls; then + TLS_TRUE= + TLS_FALSE='#' +else + TLS_TRUE='#' + TLS_FALSE= +fi + + +if $tls; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gnutls_certificate_set_verify_function in -lgnutls" >&5 +$as_echo_n "checking for gnutls_certificate_set_verify_function in -lgnutls... " >&6; } +if ${ac_cv_lib_gnutls_gnutls_certificate_set_verify_function+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgnutls $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gnutls_certificate_set_verify_function (); +int +main () +{ +return gnutls_certificate_set_verify_function (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_gnutls_gnutls_certificate_set_verify_function=yes +else + ac_cv_lib_gnutls_gnutls_certificate_set_verify_function=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gnutls_gnutls_certificate_set_verify_function" >&5 +$as_echo "$ac_cv_lib_gnutls_gnutls_certificate_set_verify_function" >&6; } +if test "x$ac_cv_lib_gnutls_gnutls_certificate_set_verify_function" = xyes; then : + +$as_echo "#define HAVE_GNUTLS_SET_VERIFY_FUNCTION 1" >>confdefs.h + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gnutls_priority_set_direct in -lgnutls" >&5 +$as_echo_n "checking for gnutls_priority_set_direct in -lgnutls... " >&6; } +if ${ac_cv_lib_gnutls_gnutls_priority_set_direct+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgnutls $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gnutls_priority_set_direct (); +int +main () +{ +return gnutls_priority_set_direct (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_gnutls_gnutls_priority_set_direct=yes +else + ac_cv_lib_gnutls_gnutls_priority_set_direct=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gnutls_gnutls_priority_set_direct" >&5 +$as_echo "$ac_cv_lib_gnutls_gnutls_priority_set_direct" >&6; } +if test "x$ac_cv_lib_gnutls_gnutls_priority_set_direct" = xyes; then : + +$as_echo "#define HAVE_GNUTLS_PRIORITY_SET_DIRECT 1" >>confdefs.h + +fi + +fi + +ac_config_files="$ac_config_files Makefile doc/Makefile lib/Makefile lib/cli++/Makefile lib/fdbuf/Makefile lib/mystring/Makefile protocols/Makefile src/Makefile test/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${FDBUF_NO_MYSTRING_TRUE}" && test -z "${FDBUF_NO_MYSTRING_FALSE}"; then + as_fn_error $? "conditional \"FDBUF_NO_MYSTRING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TLS_TRUE}" && test -z "${TLS_FALSE}"; then + as_fn_error $? "conditional \"TLS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by nullmailer $as_me 2.1, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +nullmailer config.status 2.1 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; + "lib/cli++/Makefile") CONFIG_FILES="$CONFIG_FILES lib/cli++/Makefile" ;; + "lib/fdbuf/Makefile") CONFIG_FILES="$CONFIG_FILES lib/fdbuf/Makefile" ;; + "lib/mystring/Makefile") CONFIG_FILES="$CONFIG_FILES lib/mystring/Makefile" ;; + "protocols/Makefile") CONFIG_FILES="$CONFIG_FILES protocols/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..0d47061 --- /dev/null +++ b/configure.ac @@ -0,0 +1,90 @@ +AC_INIT([nullmailer], [2.1]) +AC_LANG([C++]) +AC_CONFIG_SRCDIR([lib/defines.h]) +AM_INIT_AUTOMAKE +AM_CONFIG_HEADER(config.h) +AC_PROG_MAKE_SET + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_CXX +CXX_NO_RTTI +CXX_NO_EXCEPTIONS +AC_SYS_LARGEFILE + +CFLAGS="$CFLAGS -W -Wall" +CXXFLAGS="$CXXFLAGS -W -Wall" + +AC_PROG_INSTALL +AC_PROG_RANLIB +AC_PATH_PROG(STRIP, strip) +AC_PATH_PROG(RM, rm) +AC_PATH_PROG(MKDIR, mkdir) + +dnl Checks for libraries. +AC_CHECK_LIB(xnet, socket) +AC_CHECK_LIB(inet, socket) +AC_CHECK_LIB(socket, socket) + +dnl Checks for header files. +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_HEADER_TIME +dnl AC_CHECK_HEADERS(fcntl.h shadow.h crypt.h) +AC_CHECK_HEADERS(sys/time.h unistd.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +dnl AC_TYPE_UID_T +dnl AC_TYPE_SIGNAL +dnl AC_C_INLINE +dnl AC_TYPE_PID_T +AC_TYPE_SIZE_T + +TEST_STRUCT_TM +TEST_STRUCT_UTSNAME +CHECK_NAMED_PIPE_BUG + +dnl Checks for library functions. +dnl AC_CHECK_FUNCS(gettimeofday mkdir putenv rmdir socket) +AC_CHECK_FUNCS(setenv srandom) + +AC_MSG_CHECKING(for getaddrinfo) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stddef.h> +]], [[ +getaddrinfo(NULL, NULL, NULL, NULL) +]])], [has_getaddrinfo=yes], [has_getaddrinfo=no]) +if test "$has_getaddrinfo" = yes; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GETADDRINFO,,[getaddrinfo code enabled]) +else + AC_MSG_RESULT(no) + AC_MSG_RESULT(disabled: getaddrinfo missing) +fi +AC_SUBST(HAVE_GETADDRINFO) + +AC_DEFINE(BUFSIZE, 4096, [Generic buffer size]) +AM_CONDITIONAL(FDBUF_NO_MYSTRING, false) + +AC_ARG_ENABLE(tls, + [ --enable-tls Enable SSL/TLS support], + [case "${enableval}" in + yes) tls=true; AC_DEFINE(HAVE_TLS, 1, [Build in support for TLS]) ;; + no) tls=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-tls) ;; + esac],[tls=false]) +AM_CONDITIONAL(TLS, $tls) + +if $tls; then + AC_CHECK_LIB(gnutls, gnutls_certificate_set_verify_function, + [AC_DEFINE(HAVE_GNUTLS_SET_VERIFY_FUNCTION, 1, [libgnutls has gnutls_certificate_set_verify_function])]) + AC_CHECK_LIB(gnutls, gnutls_priority_set_direct, + [AC_DEFINE(HAVE_GNUTLS_PRIORITY_SET_DIRECT, 1, [libgnutls has gnutls_priority_set_direct])]) +fi + +AC_CONFIG_FILES([Makefile doc/Makefile lib/Makefile lib/cli++/Makefile lib/fdbuf/Makefile lib/mystring/Makefile protocols/Makefile src/Makefile test/Makefile]) +AC_OUTPUT @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2013-05-30.07; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/doc/DIAGRAM b/doc/DIAGRAM new file mode 100644 index 0000000..4557037 --- /dev/null +++ b/doc/DIAGRAM @@ -0,0 +1,25 @@ + sendmail --------------- mailq + / \ + / \ + / \ +nullmailer-inject nullmailer-smtpd + \ / + \ / + \ / + nullmailer-inject + | + | + | + nullmailer-queue + | + | + | + QUEUE/tmp -> QUEUE/queue -> QUEUE/failed + | + | + | + nullmailer-send ---- nullmailer-dsn + | + | + | + BIN/PROTOCOL diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..c3428b8 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,9 @@ +# info_TEXINFOS = nullmailer.texi +man_MANS = \ + nullmailer-dsn.1 \ + nullmailer-inject.1 \ + sendmail.1 \ + nullmailer.7 \ + nullmailer-queue.8 \ + nullmailer-send.8 +EXTRA_DIST = DIAGRAM $(man_MANS) diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..9b65515 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,584 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man7dir)" \ + "$(DESTDIR)$(man8dir)" +man7dir = $(mandir)/man7 +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HAVE_GETADDRINFO = @HAVE_GETADDRINFO@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RM = @RM@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# info_TEXINFOS = nullmailer.texi +man_MANS = \ + nullmailer-dsn.1 \ + nullmailer-inject.1 \ + sendmail.1 \ + nullmailer.7 \ + nullmailer-queue.8 \ + nullmailer-send.8 + +EXTRA_DIST = DIAGRAM $(man_MANS) +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-man7: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man7dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man7dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man7dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.7[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^7][0-9a-z]*$$,7,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man7dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man7dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man7dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man7dir)" || exit $$?; }; \ + done; } + +uninstall-man7: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man7dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.7[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^7][0-9a-z]*$$,7,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man7dir)'; $(am__uninstall_files_from_dir) +install-man8: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man8dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.8[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(MANS) +installdirs: + for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man7dir)" "$(DESTDIR)$(man8dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 install-man7 install-man8 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-man + +uninstall-man: uninstall-man1 uninstall-man7 uninstall-man8 + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ + ctags-am distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-man1 install-man7 \ + install-man8 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags-am \ + uninstall uninstall-am uninstall-man uninstall-man1 \ + uninstall-man7 uninstall-man8 + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/nullmailer-dsn.1 b/doc/nullmailer-dsn.1 new file mode 100644 index 0000000..5a321a1 --- /dev/null +++ b/doc/nullmailer-dsn.1 @@ -0,0 +1,125 @@ +.TH nullmailer-dsn 1 +.SH NAME +nullmailer-dsn \- Reformat a queued message into a delivery status notification (DSN) +.SH SYNOPSIS +.B nullmailer-dsn +[ +.B options +] +.I status-code +< +.I message +.SH DESCRIPTION +This program reads a nullmailer queue message from standard input, +transforms it into a delivery status notification, and writes the result +to standard output. The output is formatted to be fed into +.BR nullmailer-queue . +.P +All times in the options are expressed as seconds since midnight GMT January 1, 1970 (the UNIX epoch). +.SH OPTIONS +.TP +.BI \-\-diagnostic\-code= STRING +Sets the actual diagnostic code issued by the mail transport. Must be in the form of +"\fItype\fR; \fItext\fR", where +.I type +would typically be the protocol name, such as +.BR SMTP . +This adds a +.B Diagnostic-Code +header for each recipient. +.TP +.BI \-\-envelope\-id= STRING +Original envelope ID. Setting this adds a +.B Original-Envelope-Id +header to the delivery status section. +.TP +.BI \-\-last\-attempt= TIME +Sets the time of the last attempted delivery. Defaults to the access time of the input message. +This sets the date in the +.B Last-Attempt-Date +header for each recipient. +.TP +.BI \-\-max\-lines= COUNT +Sets the maximum number of lines of the original message to copy into the generated message. +A value of zero copies only the original header. +Negative values copy the whole message. +Defaults to +.I bouncelines +below, or zero if that is empty. +.TP +.BI \-\-orig\-timestamp= TIME +Sets the time of the original message. Defaults to the change time of +the input message. This sets the date in the +.B Arrival-Date +header in the delivery status section. +.TP +.BI \-\-remote= STRING +Sets the name of the remote MTA server. +This adds a +.B Remote-MTA +header for each recipient. +.TP +.BI \-\-retry\-until= TIME +Sets the time of the (future) final delivery attempt. No default. This adds a +.B Will-Retry-Until +header for each recipient. +.SH RETURN VALUE +Exits 0 if it was successful, otherwise it prints a diagnostic message +to standard error and exits 1. +.SH CONTROL FILES +.TP +.B adminaddr +If +.B doublebounceto +is empty, double bounces are delivered to this address instead. +If no address is configured, double bounces are not generated. +.TP +.B bouncelines +Sets the maximum number of lines of the original message to copy. +May be overridden by +.B \-\-max\-lines +as above. +.TP +.B bounceto +The address to which all bounces should be sent. +If it is empty, the original sender address is used. +.TP +.B defaultdomain +The content of this file is appended to any host name that does not +contain a period (except +.BR localhost ), +including +.I defaulthost +and +.IR idhost . +Defaults to the value of the +.B me +control file, if it exists, otherwise the literal name +.BR defaultdomain . +.TP +.B defaulthost +The content of this file is appended to any address that is missing a +host name. +Defaults to the value of the +.I me +control file, if it exists, otherwise the literal name +.BR defaulthost . +.TP +.B doublebounceto +If the original sender was empty (the original message was a delivery +status or disposition notification), the double bounce is sent to the +address in this file. +.TP +.B idhost +The content of this file is used when building the message-id string +for the message. +Defaults to the canonicalized value of +.IR defaulthost . +.TP +.B me +The fully-qualified host name of the computer running nullmailer. +Defaults to the literal name +.BR me . +.SH SEE ALSO +nullmailer-queue(8), +nullmailer-send(8) diff --git a/doc/nullmailer-inject.1 b/doc/nullmailer-inject.1 new file mode 100644 index 0000000..6acae7b --- /dev/null +++ b/doc/nullmailer-inject.1 @@ -0,0 +1,256 @@ +.TH nullmailer-inject 1 +.SH NAME +nullmailer-inject \- Reformat and inject a message into the queue. +.SH SYNOPSIS +.B nullmailer-inject +[\-a] +[\-b] +[\-e] +[\-f sender] +[\-h] +.I [recipient [recipient ...]] +.SH DESCRIPTION +This program reads a email message from standard input, reformats its +header to comply with RFC822, and sends the resulting message to the +queue. +.SS HEADER FIELDS +The following lines are parsed for recipient addresses: +.IR To , +.IR Cc , +.IR Bcc , +.IR Apparently-To , +.IR Resent-To , +.IR Resent-Cc , +and +.IR Resent-Bcc . + +The following sender address lines are parsed and rewritten: +.IR Sender , +.IR From , +.IR Reply-To , +.IR Return-Path , +.IR Return-Receipt-To , +.IR Errors-To , +.IR Resent-Sender , +.IR Resent-From , +and +.IR Resent-Reply-To . +If the +.I Return-Path +header field is present and contains a single address, its contents +will be used to set the envelope sender address. + +If the message contains any of the following fields, it is treated as +a resent message: +.IR Resent-Sender , +.IR Resent-From , +.IR Resent-Reply-To , +.IR Resent-To , +.IR Resent-Cc , +.IR Resent-Bcc , +.IR Resent-Date , +.IR Resent-Message-ID . +If the message is resent, only the recipient fields prefixed with +.I Resent- +are examined for addresses. + +Any occurrences of +.IR Bcc , +.IR Resent-Bcc , +.IR Return-Path , +or +.I Content-Length +are discarded after they are parsed (if necessary). + +If the header lacks a +.I Message-Id +field, a unique string is generated and added to the message. +If the header lacks a +.I Date +field, the current local date and time in RFC822 format is appended to +the message. +If the message has no +.I To +or +.I Cc +fields, the following line is appended to the message: + +.EX + Cc: recipient list not shown: ; +.EE +.SS ADDRESS LISTS +Address lists are expected to follow the syntax set out in RFC822. +The following is a simplified explanation of the syntax. + +An address list is list of addresses separated by commas. +An individual address may have one of the following three forms: +.IR user@fqdn , +.IR comment <user@fqdn> , +or +.IR phrase: address-list; . +Any of the first two forms may be used within the address list of the +third form. +Any word containing special characters must be placed in double quotes +and the special characters must be preceded with a backslash. +Comments may be placed between addresses in parenthesis. +All comments are ignored. + +Addresses lists are reformatted as they are parsed for ease of later +re-parsing when the message reaches the destination(s). +If an address is missing a fqdn, +.B nullmailer-inject +adds one. +.SH OPTIONS +.TP +.I \-a +Use only the command line arguments as recipient addresses. +Ignore the header recipient lines. +.TP +.I \-b +Use both the command line arguments and data from the message header +as recipient addresses. +.TP +.I \-e +Use either the command line arguments (if there are any) or data from +the message header (if there are no arguments) as the recipient +addresses. +.TP +.I \-f sender +Set the envelope sender address to +.IR sender . +.TP +.I \-h +Use only data from the message header as the recipient addresses. +.TP +.I \-n +Do not queue the message, but print the reformatted contents to +standard output. +.TP +.I \-v +Print out the envelope (sender and recipient addresses) preceding the +message when printing the message to standard output. +.SH RETURN VALUE +Exits 0 if it was successful, otherwise it prints a diagnostic message +to standard error and exits 1. +.SH ENVIRONMENT +The environment variable +.BR NULLMAILER_FLAGS +is parsed and the behavior of +.B nullmailer-inject +is modified if any of the following letters are present: +.TP +.B c +Use "address (comment)" style in the generated +.B From +field instead of the default "comment <address>" style. +.TP +.B f +Ignore and remove any +.B From +header lines and always insert a generated one. +.TP +.B i +Ignore and remove any +.B Message-Id +header lines. +.TP +.B s +Ignore and remove any +.B Return-Path +header lines. +.TP +.B t +Insert a +.BR To +line containing a list of the recipients if the header does not +contain either a +.B To +or a +.B Cc +field. +If the message is determined to be a resent message (see above), a +.B Resent-To +field is added if the header does not contain either a +.BR Resent-To +or a +.BR Resent-Cc +field. +.PP +The user name is set by +.BR NULLMAILER_USER , +.BR MAILUSER , +.BR USER , +or +.BR LOGNAME , +whichever comes first. If none of the above are set the name is taken +from the password file, or set to +.I unknown +if that fails. + +The host name is set by the canonicalized value of +.BR NULLMAILER_HOST , +.BR MAILHOST , +or +.BR HOSTNAME , +whichever comes first, or the +.I defaulthost +config file if none of the above are set (see below). + +The full name of the user is set by +.BR NULLMAILER_NAME , +.BR MAILNAME , +or +.BR NAME , +whichever comes first. + +The user and host name of the envelope sender default to the user and +host name set above, but may be overridden by +.BR NULLMAILER_SUSER +and +.BR NULLMAILER_SHOST . + +If +.BR NULLMAILER_QUEUE +is set, the program named is used in place of +.B nullmailer-queue +to queue the formatted message. +.SH CONTROL FILES +When reading the following files, a single line is read and stripped +of all leading and trailing whitespace characters. +.TP +.B defaultdomain +The content of this file is appended to any host name that does not +contain a period (except +.BR localhost ), +including +.I defaulthost +and +.IR idhost . +Defaults to the value of the +.B me +control file, if it exists, otherwise the literal name +.BR defaultdomain . +.TP +.B defaulthost +The content of this file is appended to any address that is missing a +host name. +Defaults to the value of the +.I me +control file, if it exists, otherwise the literal name +.BR defaulthost . +.TP +.B idhost +The content of this file is used when building the message-id string +for the message. +Defaults to the canonicalized value of +.IR defaulthost . +.TP +.B me +The fully-qualified host name of the computer running nullmailer. +Defaults to the literal name +.BR me . +.SH SEE ALSO +nullmailer-queue(8) +.SH NOTES +This document glosses over very many details of how address parsing +and rewriting actually works (among other things). diff --git a/doc/nullmailer-queue.8 b/doc/nullmailer-queue.8 new file mode 100644 index 0000000..291ea65 --- /dev/null +++ b/doc/nullmailer-queue.8 @@ -0,0 +1,53 @@ +.TH nullmailer-queue 8 +.SH NAME +nullmailer-queue \- insert mail messages into the queue +.SH SYNOPSIS +.B nullmailer-queue +.SH DESCRIPTION +This program reads a formatted mail message from standard input and +safely injects it into the outgoing mail queue. +.PP +The data sent into standard input is expected to have the following +format: one line containing the envelope sender, one or more lines +containing the recipients, a single blank line, and then the contents +of the message exactly as it is to be transmitted to the destination. +All lines are terminated with a single line-feed character. +All addresses must contain a fully-qualified domain name. +.PP +.SH RETURN VALUE +Exits 0 if it successfully queues the message. +If it failed to queue the message, it exits 1 and prints an error +message to stdandard output. +.SH CONTROL FILES +.TP +.B adminaddr +If this file is not empty, all recipients to users at either +"localhost" (the literal string) or the canonical host name (from the +.I me +control file) are remapped to this address. +This is provided to allow local daemons to be able to send email to +"somebody@localhost" and have it go somewhere sensible instead of +being bounced by your relay host. To send to multiple addresses, put +them all on one line separated by a comma. +.TP +.B allmailfrom +If this file is not empty, its contents will override the envelope +sender on all messages. +.SH OTHER FILES +.TP +.B /var/spool/nullmailer/queue +The directory into which the completed messages are moved. +.TP +.B /var/spool/nullmailer/tmp +The directory in which messages are formed temporarily. +.TP +.B /var/spool/nullmailer/trigger +A pipe used to trigger +.BR nullmailer-send +to immediately start sending the message from the queue. +.SH SEE ALSO +nullmailer-inject(1), +nullmailer-send(8) +.SH LIMITATIONS +This program should enforce system-wide configurable message length +limits. diff --git a/doc/nullmailer-send.8 b/doc/nullmailer-send.8 new file mode 100644 index 0000000..34e5f96 --- /dev/null +++ b/doc/nullmailer-send.8 @@ -0,0 +1,204 @@ +.TH nullmailer-send 8 +.SH NAME +nullmailer-send \- Send queued messages +.SH SYNOPSIS +.B nullmailer-send +.SH DESCRIPTION +This program is responsible for coordinating the transmission of +messages that have been queued by +.BR nullmailer-queue . +It uses a variety of protocol modules to deliver the messages from the +queue to remote "smart" servers. +.P +When the program starts, the queue is scanned to build a list of +messages to send. +The queue is rescanned when either the trigger is pulled, or after +.B pausetime +seconds have elapsed after the last failed delivery. +When there are no messages in the queue, nullmailer does no rescanning +until the trigger is pulled. +Pulling the trigger consists of opening up the trigger named pipe and +writing a single byte to it, which causes this program to be awakened +(if it's not already processing the queue). +This procedure is done by +.B nullmailer-queue +to ensure that messages are delivered immediately. +You can start delivery by hand from the command line like this: + +.EX + echo 1 > trigger +.EE +.P +Delivery of messages consists of reading the list of remote servers and +then trying to deliver the messages to these servers as follows. +For each remote in the list, the named protocol handler is executed once +for each message remaining in the queue. +If the protocol handler succeeds, the message is removed from the queue +and processing continues with the next message. +If the protocol handler reports a permanent failure +or the message has been in the queue longer than +.IR queuelifetime , +the message is moved into the +.B failed +queue and a bounce message is generated with +.BR nullmailer-dsn . +If any messages remain in the queue, processing of the remaining +messages continues with the next remote. +When all the remotes have been tried, +.B nullmailer-send +sleeps for a number of seconds specified by +.B pausetime +before retrying sending the contents of the queue. +.SH CONTROL FILES +All the control files are reread each time the queue is run. +.TP +.B helohost +Sets the environment variable +.B $HELOHOST +which is used by the SMTP protocol module to set the parameter given to +the +.I HELO +command. Defaults to the value of the +.B me +configuration file. +.TP +.B maxpause +The maximum time to pause between successive queue runs, in seconds. +Defaults to 24 hours +.RB ( 86400 ). +.TP +.B pausetime +The minimum time to pause between successive queue runs +when there are messages in the queue, in seconds. +Defaults to 1 minute +.RB ( 60 ). +Each time this timeout is reached, the timeout is doubled to a maximum +of +.BR maxpause . +After new messages are injected, the timeout is reset. +If this is set to +.BR 0 , +nullmailer-send will exit immediately after going through the queue once +(one-shot mode). +.TP +.B queuelifetime +The maximum time a message is allowed to live in the queue before being +considered permanently failed, in seconds. Defaults to 7 days +.RB ( 604800 ). +.TP +.B remotes +This file contains a list of remote servers to which to send each +message. +Each line of this file contains a remote host name or address followed +by an optional protocol string, separated by white space. +The protocol name defaults to +.BR smtp , +and may be followed by additional options for that module. +See the "PROTOCOL OPTIONS" section for a list of the available options. +The options may optionally be prefixed by +.I -- +but this is not required. +The line is parsed according to standard shell quoting rules. +For example, to connect to port 2525 on your SMTP smart host, +which also requires SMTP authentication, and initiate TLS with +STARTTLS, use: + +.EX + smarthost.dom smtp port=2525 starttls user=user pass='my pass phrase' +.EE + +Blank lines and lines starting with a pound (\fI#\fR) are ignored. +.TP +.B sendtimeout +The time to wait for a remote module listed above to complete sending a +message before killing it and trying again, in seconds. +Defaults to 1 hour +.RB ( 3600 ). +If this is set to +.BR 0 , +.B nullmailer-send +will wait forever for messages to complete sending. +.SH "PROTOCOL OPTIONS" +.TP +.B port=\fIPORT +Set an alternate port number to connect to on the remote host. For example, SMTP may use +.B port=587 +for the alternate SMTP "submission" port. +.TP +.B user=\fIUSERNAME +Set the SMTP authentication user name. +.TP +.B pass=\fIPASSWORD +Set the SMTP authentication password. +.TP +.BI source= HOSTNAME +Set the source address for connections to the remote host. +.TP +.B auth-login +Force SMTP "AUTH LOGIN" mode instead of auto-detecting. +.TP +.B tls +Connect using TLS. +This will automatically switch the default port to +.BR 465 . +.TP +.B ssl +Alias for the +.B tls +option for compatibility. +.TP +.B starttls +Use the +.B STARTTLS +command to initiate a TLS session. +.TP +.B x509certfile=\fIFILENAME +Set the filename for a TLS client certificate to send to the server. +.TP +.B x509keyfile=\fIFILENAME +Set the filename for the private key for a TLS client certificate. +Defaults to the same file name as +.BR x509certfile . +.TP +.B x509cafile=\fIFILENAME +Set the TLS certificate authority trust filename. Defaults to +.BR /etc/ssl/certs/ca-certificates.crt . +.TP +.B x509crlfile=\fIFILENAME +Set the TLS certificate revocation list filename. +.TP +.B x509fmtder +Specify that TLS X.509 files above are in DER format instead of PEM. +.TP +.B insecure +Don't abort a TLS connection if the server certificate fails validation. +Use this only if you know the server uses an invalid certificate. +.TP +.B tls-anon-auth +Use TLS anonymous authentication - replacing certificate authentication. +This means no external certificates or passwords are needed to set up the connection. +With this option your connection is vulnerable to man-in-the-middle (active or redirection) attacks. +However, the data are integrity protected and encrypted from passive eavesdroppers. +This option must be used with the insecure option - to acknowledge that you know what you are doing. +.SH FILES +.TP +.B /var/spool/nullmailer/failed +The failed message queue. +.TP +.B /var/spool/nullmailer/queue +The outgoing message queue. +.TP +.B /var/spool/nullmailer/trigger +A trigger file to cause immediate delivery. +.TP +.B /usr/local/etc/nullmailer +The configuration directory. +.TP +.B /usr/local/libexec/nullmailer +The protocol program directory. +.SH SEE ALSO +nullmailer-dsn(1), +nullmailer-inject(1), +nullmailer-queue(8), +mailq(1) +http://www.postfix.org/TLS_README.html on how to setup a certificate-less Postfix SMTP server diff --git a/doc/nullmailer.7 b/doc/nullmailer.7 new file mode 100644 index 0000000..6ccb524 --- /dev/null +++ b/doc/nullmailer.7 @@ -0,0 +1,37 @@ +.TH nullmailer 7 +.SH NAME +nullmailer \- Overview of nullmailer documentation +.SH INTRODUCTION +.B nullmailer +is a simple and secure relay-only mail transport agent. +.P +Documentation on how messages are reformatted and injected into the +queue can be found in +.BR nullmailer-inject (1). +Documentation on how messages are actually inserted into the queue can +be found in +.BR nullmailer-queue (8). +The process of sending queued messages is described in +.BR nullmailer-send (8). +.P +The following table lists all the control files used by +.BR nullmailer . +.P +.RS +.nf +.ta 5c +control file used by +.I adminaddr \fBnullmailer-dsn\fR, \fBnullmailer-queue +.I allmailfrom \fBnullmailer-queue +.I defaultdomain \fBnullmailer-dsn\fR, \fBnullmailer-inject +.I defaulthost \fBnullmailer-dsn\fR, \fBnullmailer-inject +.I doublebounceto \fBnullmailer-dsn +.I helohost \fBnullmailer-send +.I idhost \fBnullmailer-dsn\fR, \fBnullmailer-inject +.I maxpause \fBnullmailer-send +.I me \fBnullmailer-dsn\fR, \fBnullmailer-inject +.I pausetime \fBnullmailer-send +.I remotes \fBnullmailer-send +.I sendtimeout \fBnullmailer-send +.fi +.RE diff --git a/doc/sendmail.1 b/doc/sendmail.1 new file mode 100644 index 0000000..705034f --- /dev/null +++ b/doc/sendmail.1 @@ -0,0 +1,93 @@ +.TH sendmail 1 +.SH NAME +sendmail \- sendmail emulator interface for nullmailer +.SH SYNOPSIS +.B sendmail +[ +.B flags +] [ +.I recipients +] < +.I message +.SH DESCRIPTION +This program is a front end program for +.B nullmailer-inject +and +.BR nullmailer-smtpd . +It is used by programs that expect a +.I sendmail +interface for sending email. +After parsing the command-line arguments, this program executes either +.B nullmailer-inject +or +.B nullmailer-smtpd +depending on the presence of the +.I \-bs +option on the command-line. +See the documentation for +.B nullmailer-inject +for details on how messages are reformatted and queued. +.SH OPTIONS +.TP +.B \-B TYPE +.TP +.B \-C FILE +.TP +.B \-d DEBUG +.TP +.B \-h COUNT +.TP +.B \-i +.TP +.B \-L TAG +.TP +.B \-N DSN +.TP +.B \-n +.TP +.B \-O OPTION +.TP +.B \-o OPTION +.TP +.B \-p PROTOCOL +.TP +.B \-q TIME +.TP +.B \-R RETURN +.TP +.B \-U +.TP +.B \-V ENVID +.TP +.B \-v +.TP +.B \-X LOGFILE +Ignored for compatibility +.TP +.B \-bm +Read mail from standard input (default). +.TP +.B \-bp +List information about mail queue. This executes +.BR mailq . +.TP +.B \-bs +Use the SMTP protocol on standard input and standard output. This +executes +.BR nullmailer-smtpd . +.TP +.B \-F ADDRESS +Sets the full name of the sender. +.TP +.B \-f ADDRESS +Sets the envelope sender address. +.TP +.B \-r ADDRESS +An alternate and obsolete form of the \-f flag. +.TP +.B \-t +Read message for recipients and ignore the command-line arguments. +.SH SEE ALSO +mailq(1), +nullmailer-inject(1), +nullmailer-smtpd(1) diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..88e5b35 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,44 @@ +SUBDIRS = cli++ fdbuf mystring +noinst_LIBRARIES = libmisc.a libnullmailer.a +noinst_HEADERS = list.h +EXTRA_DIST = make_defines.sh listtest.cc mergelib.sh +CLEANFILES = defines.cc + +libmisc_a_SOURCES = \ + ac/dirent.h ac/time.h ac/wait.h \ + address.h address.cc \ + argparse.h argparse.cc \ + autoclose.h \ + base64.h base64.cc \ + canonicalize.h canonicalize.cc \ + configio.h config_path.cc \ + config_read.cc config_readlist.cc config_readint.cc config_syserr.cc \ + connect.h tcpconnect.cc \ + defines.h \ + errcodes.h errcodes.cc \ + hostname.h hostname.cc \ + itoa.h itoa.cc \ + makefield.cc makefield.h \ + netstring.h netstring.cc \ + forkexec.cc forkexec.h \ + selfpipe.cc selfpipe.h \ + setenv.cc setenv.h +nodist_libmisc_a_SOURCES = defines.cc + +libnullmailer_a_SOURCES = +libnullmailer.a: mergelib.sh libmisc.a fdbuf/libfdbuf.a \ + mystring/libmystring.a Makefile + $(RM) -f libnullmailer.a + sh $(srcdir)/mergelib.sh libnullmailer.a \ + libmisc.a \ + fdbuf/libfdbuf.a \ + mystring/libmystring.a + +defines.cc: Makefile make_defines.sh + @echo Creating defines.cc + @sh $(srcdir)/make_defines.sh \ + @localstatedir@/spool/nullmailer \ + @sysconfdir@/nullmailer \ + @libexecdir@/nullmailer \ + @bindir@ \ + @sbindir@ diff --git a/lib/Makefile.in b/lib/Makefile.in new file mode 100644 index 0000000..50c8159 --- /dev/null +++ b/lib/Makefile.in @@ -0,0 +1,738 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = lib +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libmisc_a_AR = $(AR) $(ARFLAGS) +libmisc_a_LIBADD = +am_libmisc_a_OBJECTS = address.$(OBJEXT) argparse.$(OBJEXT) \ + base64.$(OBJEXT) canonicalize.$(OBJEXT) config_path.$(OBJEXT) \ + config_read.$(OBJEXT) config_readlist.$(OBJEXT) \ + config_readint.$(OBJEXT) config_syserr.$(OBJEXT) \ + tcpconnect.$(OBJEXT) errcodes.$(OBJEXT) hostname.$(OBJEXT) \ + itoa.$(OBJEXT) makefield.$(OBJEXT) netstring.$(OBJEXT) \ + forkexec.$(OBJEXT) selfpipe.$(OBJEXT) setenv.$(OBJEXT) +nodist_libmisc_a_OBJECTS = defines.$(OBJEXT) +libmisc_a_OBJECTS = $(am_libmisc_a_OBJECTS) \ + $(nodist_libmisc_a_OBJECTS) +libnullmailer_a_AR = $(AR) $(ARFLAGS) +libnullmailer_a_LIBADD = +am_libnullmailer_a_OBJECTS = +libnullmailer_a_OBJECTS = $(am_libnullmailer_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libmisc_a_SOURCES) $(nodist_libmisc_a_SOURCES) \ + $(libnullmailer_a_SOURCES) +DIST_SOURCES = $(libmisc_a_SOURCES) $(libnullmailer_a_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HAVE_GETADDRINFO = @HAVE_GETADDRINFO@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RM = @RM@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = cli++ fdbuf mystring +noinst_LIBRARIES = libmisc.a libnullmailer.a +noinst_HEADERS = list.h +EXTRA_DIST = make_defines.sh listtest.cc mergelib.sh +CLEANFILES = defines.cc +libmisc_a_SOURCES = \ + ac/dirent.h ac/time.h ac/wait.h \ + address.h address.cc \ + argparse.h argparse.cc \ + autoclose.h \ + base64.h base64.cc \ + canonicalize.h canonicalize.cc \ + configio.h config_path.cc \ + config_read.cc config_readlist.cc config_readint.cc config_syserr.cc \ + connect.h tcpconnect.cc \ + defines.h \ + errcodes.h errcodes.cc \ + hostname.h hostname.cc \ + itoa.h itoa.cc \ + makefield.cc makefield.h \ + netstring.h netstring.cc \ + forkexec.cc forkexec.h \ + selfpipe.cc selfpipe.h \ + setenv.cc setenv.h + +nodist_libmisc_a_SOURCES = defines.cc +libnullmailer_a_SOURCES = +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .cc .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu lib/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libmisc.a: $(libmisc_a_OBJECTS) $(libmisc_a_DEPENDENCIES) $(EXTRA_libmisc_a_DEPENDENCIES) + $(AM_V_at)-rm -f libmisc.a + $(AM_V_AR)$(libmisc_a_AR) libmisc.a $(libmisc_a_OBJECTS) $(libmisc_a_LIBADD) + $(AM_V_at)$(RANLIB) libmisc.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/address.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argparse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/canonicalize.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config_path.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config_read.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config_readint.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config_readlist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config_syserr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defines.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errcodes.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forkexec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/itoa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/makefield.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netstring.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selfpipe.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setenv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcpconnect.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LIBRARIES) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-noinstLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + +libnullmailer.a: mergelib.sh libmisc.a fdbuf/libfdbuf.a \ + mystring/libmystring.a Makefile + $(RM) -f libnullmailer.a + sh $(srcdir)/mergelib.sh libnullmailer.a \ + libmisc.a \ + fdbuf/libfdbuf.a \ + mystring/libmystring.a + +defines.cc: Makefile make_defines.sh + @echo Creating defines.cc + @sh $(srcdir)/make_defines.sh \ + @localstatedir@/spool/nullmailer \ + @sysconfdir@/nullmailer \ + @libexecdir@/nullmailer \ + @bindir@ \ + @sbindir@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/ac/dirent.h b/lib/ac/dirent.h new file mode 100644 index 0000000..5b0f191 --- /dev/null +++ b/lib/ac/dirent.h @@ -0,0 +1,17 @@ +#include <sys/types.h> +#if HAVE_DIRENT_H +# include <dirent.h> +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif +# if HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif +# if HAVE_NDIR_H +# include <ndir.h> +# endif +#endif diff --git a/lib/ac/time.h b/lib/ac/time.h new file mode 100644 index 0000000..10d1136 --- /dev/null +++ b/lib/ac/time.h @@ -0,0 +1,10 @@ +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif diff --git a/lib/ac/wait.h b/lib/ac/wait.h new file mode 100644 index 0000000..665ced5 --- /dev/null +++ b/lib/ac/wait.h @@ -0,0 +1,10 @@ +#include <sys/types.h> +#if HAVE_SYS_WAIT_H +# include <sys/wait.h> +#endif +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif diff --git a/lib/address.cc b/lib/address.cc new file mode 100644 index 0000000..6aea5b7 --- /dev/null +++ b/lib/address.cc @@ -0,0 +1,672 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include <ctype.h> +#include "canonicalize.h" +#include "mystring/mystring.h" +#include "list.h" + +#define LSQBRACKET '[' +#define RSQBRACKET ']' +#define QUOTE '"' +#define CR '\n' +#define LPAREN '(' +#define RPAREN ')' + +enum node_type { + EMPTY = 0, + // Full tokens, with string content: + ATOM = 'A', + QUOTED_STRING = 'Q', + DOMAIN_LITERAL = 'D', + COMMENT = 'C', + // Special characters, no content: + LABRACKET = '<', + RABRACKET = '>', + AT = '@', + COMMA = ',', + SEMICOLON = ';', + COLON = ':', + ESCAPE = '\\', + PERIOD = '.', + // End of tokens + EOT = '$', +}; + +struct token +{ + const node_type type; + const bool has_ws; + const mystring str; + + token(node_type); + token(node_type, bool, mystring); +}; + +token::token(node_type t) + : type(t), has_ws(false) +{ +} + +token::token(node_type t, bool w, mystring s) + : type(t), has_ws(w), str(s) +{ +} + +struct anode : public token +{ + anode* next; + anode(node_type, const char*, const char*, const char*); + anode(node_type, bool, mystring); +}; + +anode::anode(node_type t, + const char* wstart, + const char* start, + const char* end) + : token(t, start > wstart, mystring(start, end-start)), next(0) +{ +} + +anode::anode(node_type t, bool w, mystring s) + : token(t, w, s), next(0) +{ +} + +struct result +{ + anode* next; + bool good; + mystring str; + mystring comment; + mystring addr; + + result(); + result(const result&); + result(anode*); + result(anode*, const mystring&, const mystring&, const mystring&); + bool operator!() const + { + return !good; + } + operator bool() const + { + return good; + } +}; + +result::result() + : next(0), good(0) +{ +} + +result::result(anode* n) + : next(n), good(1) +{ +} + +result::result(anode* n, const mystring& s, + const mystring& c, const mystring& l) + : next(n), good(1), str(s), comment(c), addr(l) +{ +} + +result::result(const result& r) + : next(r.next), good(r.good), str(r.str), comment(r.comment), addr(r.addr) +{ +} + +#ifndef TRACE +#define ENTER(R) +#define FAIL(MSG) return result() +#define RETURNR(R) return R +#define RETURN(N,S,C,L) return result(N,S,C,L) +#else +#include "fdbuf/fdbuf.h" +static const char indentstr[] = " "; +static const char* indent = indentstr + sizeof indentstr - 1; +#define ENTER(R) do{ fout << indent-- << __FUNCTION__ << ": \"" << node->str << "\": " << R << endl; }while(0) +#define FAIL(MSG) do{ fout << ++indent << __FUNCTION__ << ": failed: " << MSG << endl; return result(); }while(0) +#define RETURNR(R) do{ fout << ++indent << __FUNCTION__ << ": succeeded str=" << R.str << " comment=" << R.comment << " addr=" << R.addr << endl; return (R); }while(0) +#define RETURN(N,S,C,L) do{ result _result(N,S,C,L); RETURNR(_result); }while(0) +#endif + +#define RULE(X) static result match_##X(anode* node) +#define MATCHTOKEN(X) do{ if(node->type != X) FAIL("node is not type " #X); else node = node->next; }while(0) +#define MATCHRULE(V,R) result V = match_##R(node); if(!V) FAIL("did not match " #R); +#define OR_RULE(ALT1,ALT2) { result r=match_##ALT1(node); if(r) RETURNR(r); }{ result r=match_##ALT2(node); if(r) RETURNR(r); } FAIL("did not match " #ALT1 " OR " #ALT2); + +static bool issymbol(char c) +{ + switch(c) { + case LPAREN: case RPAREN: + case LABRACKET: case RABRACKET: + case LSQBRACKET: case RSQBRACKET: + case AT: case COMMA: + case SEMICOLON: case COLON: + case ESCAPE: case QUOTE: case PERIOD: + return true; + default: + return false; + } +} + +static bool isctl(char c) +{ + return (c >= 0 && c <= 31) || (c == 127); +} + +static bool isqtext(char c) +{ + return c && c != QUOTE && c != ESCAPE; +} + +static bool isdtext(char c) +{ + return c && c != LSQBRACKET && c != RSQBRACKET && + c != ESCAPE && c != CR; +} + +// quoted-pair = ESCAPE CHAR +static bool isqpair(const char* ptr) +{ + return *ptr && *ptr == ESCAPE && + *(ptr+1); +} + +static bool isatom(char ch) +{ + return !(isspace(ch) || issymbol(ch) || isctl(ch)); +} + +static anode* tokenize_atom(const char* wstart, const char* &ptr) +{ + if(!isatom(*ptr)) return 0; + const char* start = ptr; + do { + ++ptr; + } while(isatom(*ptr)); + return new anode(ATOM, wstart, start, ptr); +} + +static anode* tokenize_comment(const char* wstart, const char* &ptr) +{ + if(*ptr != LPAREN) return 0; + unsigned count = 0; + const char* start = ptr; + char ch = *ptr; + while(ch) { + if(isqpair(ptr)) + ++ptr; + else if(ch == LPAREN) + ++count; + else if(ch == RPAREN) { + --count; + if(!count) + return new anode(COMMENT, wstart, start, ++ptr); + } + else if(ch == CR) + return 0; // ERROR + ++ptr; + ch = *ptr; + } + return 0; // ERROR +} + +static anode* tokenize_domain_literal(const char* wstart, const char* &ptr) +{ + if(*ptr != LSQBRACKET) return 0; + const char* start = ptr; + ++ptr; + while(isspace(*ptr)) ++ptr; + for(; *ptr; ++ptr) { + if(isdtext(*ptr)) + continue; + else if(isqpair(ptr)) + ++ptr; + else + break; + } + while(isspace(*ptr)) ++ptr; + if(*ptr != RSQBRACKET) + return 0; // ERROR + return new anode(DOMAIN_LITERAL, wstart, start, ptr); +} + +static anode* tokenize_quoted_string(const char* wstart, const char* &ptr) +{ + if(*ptr != QUOTE) return 0; + const char* start = ptr; + for(++ptr; *ptr; ++ptr) { + if(isqtext(*ptr)) + continue; + else if(isqpair(ptr)) + ++ptr; + else + break; + } + if(*ptr != QUOTE) return 0; + ++ptr; + return new anode(QUOTED_STRING, wstart, start, ptr); +} + +static anode* tokenize(const char* &ptr) +{ + const char* wstart = ptr; + while(isspace(*ptr)) ++ptr; + char ch = *ptr; + switch(ch) { + case 0: + return new anode(EOT, wstart, ptr, ptr); + case LABRACKET: + case RABRACKET: + case AT: + case COMMA: + case SEMICOLON: + case COLON: + case ESCAPE: + case PERIOD: + ++ptr; + return new anode((node_type)ch, wstart, ptr-1, ptr); + case LPAREN: + return tokenize_comment(wstart, ptr); + case LSQBRACKET: + return tokenize_domain_literal(wstart, ptr); + case QUOTE: + return tokenize_quoted_string(wstart, ptr); + default: + return tokenize_atom(wstart, ptr); + } +} + +anode* tokenize(const mystring str) +{ + const char* ptr = str.c_str(); + anode* head = new anode(EMPTY, ptr, ptr, ptr); + anode* tail = head; + anode* tmp; + while((tmp = tokenize(ptr)) != 0) { + tail = tail->next = tmp; + if(tmp->type == EOT) { + tail = head->next; + delete head; + return tail; + } + } + return 0; +} + +static mystring quote(const mystring& in) +{ + unsigned length = in.length(); + // The result will never be more than double the length of the input plus 2 + char out[length*2 + 2 + 1]; + char* ptrout = out; + const char* ptrin = in.c_str(); + bool quoted = false; + for(; length; ++ptrin, ++ptrout, --length) { + if(*ptrin == QUOTE || *ptrin == ESCAPE) + *ptrout++ = ESCAPE; + if(issymbol(*ptrin)) + quoted = true; + *ptrout = *ptrin; + } + *ptrout = 0; + if(quoted) + return mystringjoin("\"") + out + "\""; + else + return in; +} + +static mystring unquote(const mystring& in) +{ + unsigned length = in.length(); + // The result will never be more than the length of the input + char out[length+1]; + bool modified = false; + const char* ptrin = in.c_str(); + char* ptrout = out; + if(in[0] == QUOTE && in[length-1] == QUOTE) { + length -= 2; + ptrin++; + modified = true; + } + // Skip leading whitespace before copying to out + for(; length > 0 && isspace(*ptrin); ++ptrin, --length, modified = true) + ; + for(; length; ++ptrin, ++ptrout, --length) { + if(isqpair(ptrin)) { + ++ptrin; + --length; + modified = true; + } + *ptrout = *ptrin; + } + // Skip trailing whitespace copied into out + for(; ptrout > out && isspace(ptrout[-1]); --ptrout, modified = true) + ; + *ptrout = 0; + if(modified) + return out; + else + return in; +} + +anode* skipcomment(anode* node, mystring& comment) +{ + while(node->type == COMMENT) { + comment = comment + " " + node->str; + node = node->next; + } + return node; +} + +RULE(sub_domain) +{ + // Note atom <= domain-ref + ENTER("atom / domain-literal"); + mystring comment; + node = skipcomment(node, comment); + if(node->type == ATOM || node->type == DOMAIN_LITERAL) + RETURN(node->next, node->str, comment, node->str); + FAIL("did not match ATOM or DOMAIN-LITERAL"); +} + +RULE(domain) +{ + ENTER("sub-domain *(PERIOD sub-domain) [PERIOD]"); + MATCHRULE(r, sub_domain); + if(!r) FAIL("did not match sub-domain"); + mystring comment; + for(;;) { + node = r.next = skipcomment(r.next, comment); + if(node->type != PERIOD) + break; + r.str += PERIOD; + r.addr += PERIOD; + node = node->next; + result r1 = match_sub_domain(node); + if(r1) { + r.next = r1.next; + r.str += r1.str; + comment += r1.comment; + r.addr += r1.addr; + } + else { + r.next = node; + node = r.next = skipcomment(r.next, comment); + } + } + r.comment += comment; + RETURNR(r); +} + +RULE(route) +{ + ENTER("1#(AT domain) COLON"); + unsigned count=0; + mystring str; + mystring comment; + for(;;) { + if(node->type != AT) break; + node = node->next; + MATCHRULE(r, domain); + str += AT; + str += r.str; + comment += r.comment; + ++count; + node = r.next; + } + if(count == 0) + FAIL("matched no domains"); + node = skipcomment(node, comment); + MATCHTOKEN(COLON); + RETURN(node, str, comment, ""); +} + +RULE(word) +{ + ENTER("atom / quoted-string"); + mystring comment; + node = skipcomment(node, comment); + if(node->type == ATOM) + RETURN(node->next, node->str, comment, node->str); + else if(node->type == QUOTED_STRING) { + mystring addr = unquote(node->str); + RETURN(node->next, quote(addr), comment, addr); + } + FAIL("did not match ATOM or QUOTED-STRING"); +} + +RULE(local_part) +{ + ENTER("word *(PERIOD word)"); + MATCHRULE(r, word); + for(;;) { + node = r.next = skipcomment(r.next, r.comment); + if(node->type != PERIOD) + break; + node = node->next; + result r1 = match_word(node); + if(!r1) + break; + r.next = r1.next; + r.str += PERIOD; + r.str += r1.str; + r.comment += r1.comment; + r.addr += PERIOD; + r.addr += r1.addr; + } + RETURNR(r); +} + +RULE(addr_spec) +{ + ENTER("local-part *( AT domain )"); + MATCHRULE(r, local_part); + mystring domain; + for(;;) { + node = r.next = skipcomment(r.next, r.comment); + if(node->type != AT) + break; + node = node->next; + result r2 = match_domain(node); + if(!r2) break; + if(!!domain) { + r.str += AT; + r.str += domain; + r.addr += AT; + r.addr += domain; + } + domain = r2.addr; + r.comment += r2.comment; + r.next = r2.next; + } + canonicalize(domain); + RETURN(r.next, r.str + "@" + domain, r.comment, + r.addr + "@" + domain + "\n"); +} + +RULE(route_addr) +{ + ENTER("LABRACKET [route] addr-spec RABRACKET"); + mystring comment; + node = skipcomment(node, comment); + MATCHTOKEN(LABRACKET); + result r1 = match_route(node); + if(r1) node = r1.next; + comment += r1.comment; + MATCHRULE(r2, addr_spec); + node = r2.next; + comment += r2.comment; + node = skipcomment(node, comment); + MATCHTOKEN(RABRACKET); + RETURN(node, "<" + r2.str + ">" + comment, "", r2.addr); +} + +RULE(phrase) +{ + ENTER("word *(word / PERIOD / CFWS)"); + MATCHRULE(r1, word); + for(;;) { + if(r1.next->type == PERIOD) { + if (r1.next->has_ws) + r1.str += ' '; + r1.str += PERIOD; + r1.next = r1.next->next; + } + else { + result r2 = match_word(r1.next); + if(!r2) + break; + if (r1.next->has_ws) + r1.str += ' '; + r1.str += r2.str; + r1.comment += r2.comment; + r1.next = r2.next; + } + } + RETURNR(r1); +} + +RULE(route_spec) +{ + ENTER("[phrase] route-addr"); + result r1 = match_phrase(node); + if(r1) + node = r1.next; + MATCHRULE(r2, route_addr); + if(!r1) + RETURNR(r2); + r2.str = r1.str + r1.comment + " " + r2.str + r2.comment; + RETURNR(r2); +} + +RULE(mailbox) +{ + ENTER("route-spec / addr-spec"); + OR_RULE(route_spec, addr_spec); +} + +RULE(mailboxes) +{ + ENTER("mailbox *(*(COMMA) mailbox)"); + MATCHRULE(r1, mailbox); + r1.str += r1.comment; + r1.comment = ""; + for(;;) { + node = r1.next; + for(;;) { + node = skipcomment(node, r1.str); + if(node->type == COMMA) node = node->next; + else break; + } + if(node->type == EOT) + break; + result r2 = match_mailbox(node); + if(!r2) break; + r1.next = r2.next; + r1.str = r1.str + ", " + r2.str + r2.comment; + r1.addr += r2.addr; + } + node = skipcomment(node, r1.str); + r1.next = node; + RETURNR(r1); +} + +RULE(group) +{ + ENTER("phrase COLON [#mailboxes] SEMICOLON"); + MATCHRULE(r1, phrase); + node = r1.next; + MATCHTOKEN(COLON); + result r2 = match_mailboxes(node); + if(r2) node = r2.next; + mystring comment; + node = skipcomment(node, comment); + MATCHTOKEN(SEMICOLON); + RETURN(node, r1.str + ": " + r2.str + r2.comment + comment + ";", + "", r2.addr); +} + +RULE(address) +{ + ENTER("group / mailbox"); + OR_RULE(group, mailbox); +} + +RULE(addresses) +{ + ENTER("[address *(*(COMMA) address)] EOF"); + + // Special-case handling for empty address lists + if(node->type == EOT) RETURN(0, "", "", ""); + if(node->type == COMMENT && node->next->type == EOT) + RETURN(0, node->str, "", ""); + + MATCHRULE(r1, address); + r1.str += r1.comment; + r1.comment = ""; + for(;;) { + node = r1.next; + for(;;) { + node = skipcomment(node, r1.str); + if(node->type == COMMA) node = node->next; + else break; + } + if(node->type == EOT) + break; + result r2 = match_address(node); + if(!r2) break; + r1.next = r2.next; + r1.str = r1.str + ", " + r2.str + r2.comment; + r1.addr += r2.addr; + } + node = skipcomment(node, r1.str); + if(node->next) FAIL("Rule ended before EOF"); + RETURNR(r1); +} + +static void del_tokens(anode* node) +{ + while(node) { + anode* tmp = node->next; + delete node; + node = tmp; + } +} + +bool parse_addresses(mystring& line, mystring& list) +{ + anode* tokenlist = tokenize(line.c_str()); + if(!tokenlist) + return false; + result r = match_addresses(tokenlist); + del_tokens(tokenlist); + if(r) { + line = r.str; + list = r.addr; + return true; + } + else + return false; +} diff --git a/lib/address.h b/lib/address.h new file mode 100644 index 0000000..ca0f93a --- /dev/null +++ b/lib/address.h @@ -0,0 +1,8 @@ +#ifndef NULLMAILER__ADDRESS__H__ +#define NULLMAILER__ADDRESS__H__ + +#include "mystring/mystring.h" + +bool parse_addresses(mystring& line, mystring& list); + +#endif // NULLMAILER__ADDRESS__H__ diff --git a/lib/argparse.cc b/lib/argparse.cc new file mode 100644 index 0000000..0a231e1 --- /dev/null +++ b/lib/argparse.cc @@ -0,0 +1,61 @@ +#include <ctype.h> +#include "argparse.h" + +static const char* parse_arg(mystring& arg, const char* start, const char* end) +{ + const char* ptr; + for (ptr = start; ptr < end && ! isspace(*ptr); ++ptr) { + switch (*ptr) { + case '\'': + arg.append(start, ptr - start); + for (start = ++ptr; ptr < end && *ptr != '\''; ++ptr) ; + arg.append(start, ptr - start); + start = ptr + 1; + continue; + case '"': + arg.append(start, ptr - start); + for (start = ++ptr; ptr < end && *ptr != '\"'; ptr++) { + if (*ptr == '\\') { + arg.append(start, ptr - start); + if (++ptr < end) + arg.append(ptr, 1); + start = ++ptr; + } + } + arg.append(start, ptr - start); + start = ptr + 1; + continue; + case '\\': + arg.append(start, ptr - start); + if (++ptr < end) + arg.append(ptr, 1); + start = ++ptr; + continue; + } + } + if ((ptr - start) > 0) + arg.append(start, ptr - start); + return ptr; +} + +unsigned parse_args(arglist& lst, const mystring& str) +{ + lst.empty(); + const char* ptr = str.c_str(); + const char* end = ptr + str.length(); + unsigned count = 0; + while (ptr < end) { + // Skip any leading spaces + if (isspace(*ptr)) + ++ptr; + else { + mystring s; + ptr = parse_arg(s, ptr, end); + if (ptr == 0) + break; + lst.append(s); + ++count; + } + } + return count; +} diff --git a/lib/argparse.h b/lib/argparse.h new file mode 100644 index 0000000..589342d --- /dev/null +++ b/lib/argparse.h @@ -0,0 +1,10 @@ +#ifndef NULLMAILER__ARGPARSE__H +#define NULLMAILER__ARGPARSE__H + +#include "mystring/mystring.h" +#include "list.h" + +typedef list<mystring> arglist; +unsigned parse_args(arglist&, const mystring& str); + +#endif diff --git a/lib/autoclose.h b/lib/autoclose.h new file mode 100644 index 0000000..8bd38fd --- /dev/null +++ b/lib/autoclose.h @@ -0,0 +1,68 @@ +#ifndef NULLMAILER_AUTOCLOSE__H__ +#define NULLMAILER_AUTOCLOSE__H__ + +#include <unistd.h> + +// Simple inline wrapper to automatically close an open file descriptor +class autoclose +{ + private: + int fd; + + public: + inline autoclose(int f = -1) : fd(f) { } + inline ~autoclose() { close(); } + inline operator int() const { return fd; } + inline int operator =(int f) + { + close(); + return fd = f; + } + inline void close() + { + if (fd >= 0) { + ::close(fd); + fd = -1; + } + } +}; + +// Simple inline wrapper to handle opening and closing a pipe pair +class autoclose_pipe +{ + private: + int fds[2]; + + public: + inline autoclose_pipe() + { + fds[0] = fds[1] = -1; + } + inline ~autoclose_pipe() + { + close(); + } + inline int operator[](int i) const { return fds[i]; } + inline bool open() + { + return pipe(fds) == 0; + } + inline void close() + { + if (fds[0] >= 0) { + ::close(fds[0]); + ::close(fds[1]); + fds[0] = fds[1] = -1; + } + } + // Close one half of the pair, return the other, and mark both as if they were closed. + inline int extract(int which) + { + int result = fds[which]; + ::close(fds[1-which]); + fds[0] = fds[1] = -1; + return result; + } +}; + +#endif // NULLMAILER_AUTOCLOSE__H__ diff --git a/lib/base64.cc b/lib/base64.cc new file mode 100644 index 0000000..2492526 --- /dev/null +++ b/lib/base64.cc @@ -0,0 +1,63 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "base64.h" + +static char basis[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +void base64_encode(const mystring& in, mystring& out) +{ + size_t length; + const unsigned char* ptr; + char buf[4]; + for (length = in.length(), ptr = (const unsigned char*)in.c_str(); + length >= 3; + length -= 3, ptr += 3) { + base64_encode_chunk(ptr, 3, buf); + out.append(buf, 4); + } + if (length > 0) { + base64_encode_chunk(ptr, length, buf); + out.append(buf, 4); + } +} + +void base64_encode_chunk(const unsigned char bin[3], unsigned len, + char encoded[4]) +{ + encoded[0] = basis[bin[0] >> 2]; + switch(len) { + case 1: + encoded[1] = basis[(bin[0] << 4) & 0x3f]; + encoded[2] = encoded[3] = '='; + break; + case 2: + encoded[1] = basis[(bin[0] << 4 | bin[1] >> 4) & 0x3f]; + encoded[2] = basis[(bin[1] << 2) & 0x3f]; + encoded[3] = '='; + break; + case 3: + encoded[1] = basis[(bin[0] << 4 | bin[1] >> 4) & 0x3f]; + encoded[2] = basis[(bin[1] << 2 | bin[2] >> 6) & 0x3f]; + encoded[3] = basis[bin[2] & 0x3f]; + } +} diff --git a/lib/base64.h b/lib/base64.h new file mode 100644 index 0000000..0f5e498 --- /dev/null +++ b/lib/base64.h @@ -0,0 +1,10 @@ +#ifndef NULLMAILER_BASE64__H__ +#define NULLMAILER_BASE64__H__ + +#include "mystring/mystring.h" + +extern void base64_encode(const mystring& in, mystring& out); +extern void base64_encode_chunk(const unsigned char bin[3], unsigned len, + char encoded[4]); + +#endif // NULLMAILER_BASE64__H__ diff --git a/lib/canonicalize.cc b/lib/canonicalize.cc new file mode 100644 index 0000000..c716f8d --- /dev/null +++ b/lib/canonicalize.cc @@ -0,0 +1,38 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include "mystring/mystring.h" +#include "canonicalize.h" +#include "hostname.h" + +void canonicalize(mystring& domain) +{ + if(!domain) + domain = defaulthost; + if(domain != "localhost" && domain.find_first('.') < 0) { + if(!!defaultdomain) { + if (!!domain) domain += "."; + domain += defaultdomain; + } + } +} + diff --git a/lib/canonicalize.h b/lib/canonicalize.h new file mode 100644 index 0000000..f046aec --- /dev/null +++ b/lib/canonicalize.h @@ -0,0 +1,7 @@ +#ifndef NULLMAILER__CANONICALIZE__H__ +#define NULLMAILER__CANONICALIZE__H__ + +#include "mystring/mystring.h" +void canonicalize(mystring& domain); + +#endif // NULLMAILER__CANONICALIZE__H__ diff --git a/lib/cli++/ChangeLog b/lib/cli++/ChangeLog new file mode 100644 index 0000000..7cd88de --- /dev/null +++ b/lib/cli++/ChangeLog @@ -0,0 +1,123 @@ +2001-03-07 Bruce Guenter <bruce@bruce-guenter.dyndns.org> + + * Renamed cli.h to cli++.h + +2000-10-25 Bruce Guenter <bruce@bruce-guenter.dyndns.org> + + * cli2pod.pl (parse_options): Ignore {0,} as well as {0}. + +2000-08-15 Bruce Guenter <bruce@bruce-guenter.dyndns.org> + + * cli2pod.pl: Replaced the CLI documentation programs with this + script which outputs POD, which can be translated to man pages or + HTML (or LaTeX, or text, or FM). + +2000-08-14 Bruce Guenter <bruce@bruce-guenter.dyndns.org> + + * cli_parse.pl (parse_header_line): Rewrote the parsing to deal + with multi-line strings. + + * cli2man.pl (synopsis): Add usage string. + + * cli2html.pl (synopsis): Add usage string. + +2000-08-12 Bruce Guenter <bruce@bruce-guenter.dyndns.org> + + * cli_parse.pl, cli2html.pl, cli2man.pl: Created these programs. + +2000-08-01 Bruce Guenter <bruce@bruce-guenter.dyndns.org> + + * main.cc (show_option): Fixed several width glitches. + +2000-07-18 Bruce Guenter <bruce@bruce-guenter.dyndns.org> + + * cli.h (struct cli_option): Added new uinteger type. + + * main.cc (fill): Removed use of mystring. + +2000-07-13 Bruce Guenter <bruce@bruce-guenter.dyndns.org> + + * Removed include of mystring. + +2000-01-09 Bruce Guenter <bruceg@daedalus.bfsmedia.com> + + * main.cc (parse_short): Modified the logic here to treat a string + value immediately following a string option as the value for that + option rather than as more flags. This makes it behave much more + like the standard getopt library. + +1999-09-30 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * main.cc (show_option): Changed stringlist option string from + "=LIST" to "=ITEM". + +1999-09-29 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * main.cc (cli_option::set): Fixed problem with setting a string + list option. + +1999-09-11 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * main.cc (show_help): Split off two parts of this routine into + calc_max_width and show_option. + (show_option): Add "=INT" for integer options, and don't add extra + space for non-value long options. + (set): Use strtol instead of atoi to parse the integer string, to + allow for error checking. + (show_option): Fixed handling of string lists. + +1999-08-14 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * main.cc (set_argv0): Sets argv0 to the complete value of + argv[0], argv0dir to the part of argv[0] up to and including the + last '/' (or blank if there is none), and argv0base to the + remainder of argv[0]. This is for use in programs that determine + what to do based on the value of the program name. + +1999-07-14 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * main.cc (parse_long_eq): Fixed to account for "counter" flag + type. + (parse_long_noeq): Fixed to account for "counter" flag type. + (parse_long_eq): set() will return one, but this shouldn't return + one, so subtract one from its result. + (show_help): Added a mechanism to display default values on a + second line. + (show_help): Output a blank line before the "--help" option line. + +1999-07-04 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * main.cc (show_help): Only show a "=VALUE" for string and integer + option types. + +1999-06-30 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * messages.cc (cli_error): Moved this routine into a separate + module, and added a "cli_warning" routine. + +1999-06-25 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * main.cc (set): Added handling for two new option types: string + list and counters. A stringlist maintains a linked list of all + the given option arguments. A counter adds the flag_value to the + dataptr each time it is encountered. + (parse_short): Fixed faulty logic regarding options with values. + Need to merge parts into cli_option::set(). + +1999-06-24 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * main.cc: Rewrote the "help" option handling to stop it being a + special case, by making an internal option list that includes a + "help" option at the end of it. + (show_help): Cleaned up the option formatting to produce more + correct output. + (build_options): Removed the need to count the options. Note + that this breaks compatibility with previous versions. + (cli_error): Added this convenience function for the CLI program + to report errors and optionally exit. + (set): Added functionality to call functions when an option is + parsed, and moved some of the option parsing into class methods + from the structure. + (main): Moved the test for showing the usage information before + the test for counting command-line arguments. + diff --git a/lib/cli++/Makefile.am b/lib/cli++/Makefile.am new file mode 100644 index 0000000..7cb7392 --- /dev/null +++ b/lib/cli++/Makefile.am @@ -0,0 +1,9 @@ +noinst_LIBRARIES = libcli++.a +EXTRA_DIST = clitest.cc cli++topod.pl + +AM_CPPFLAGS = -I$(top_srcdir)/lib +#LIBS = @LIBS@ -L. -lcli++ -L../lib -lvmailmgr + +libcli___a_SOURCES = cli++.h main.cc messages.cc only_long.cc +#clitest_SOURCES = clitest.cc + diff --git a/lib/cli++/Makefile.in b/lib/cli++/Makefile.in new file mode 100644 index 0000000..a133e95 --- /dev/null +++ b/lib/cli++/Makefile.in @@ -0,0 +1,554 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = lib/cli++ +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libcli___a_AR = $(AR) $(ARFLAGS) +libcli___a_LIBADD = +am_libcli___a_OBJECTS = main.$(OBJEXT) messages.$(OBJEXT) \ + only_long.$(OBJEXT) +libcli___a_OBJECTS = $(am_libcli___a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libcli___a_SOURCES) +DIST_SOURCES = $(libcli___a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ + ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HAVE_GETADDRINFO = @HAVE_GETADDRINFO@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RM = @RM@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libcli++.a +EXTRA_DIST = clitest.cc cli++topod.pl +AM_CPPFLAGS = -I$(top_srcdir)/lib +#LIBS = @LIBS@ -L. -lcli++ -L../lib -lvmailmgr +libcli___a_SOURCES = cli++.h main.cc messages.cc only_long.cc +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/cli++/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu lib/cli++/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libcli++.a: $(libcli___a_OBJECTS) $(libcli___a_DEPENDENCIES) $(EXTRA_libcli___a_DEPENDENCIES) + $(AM_V_at)-rm -f libcli++.a + $(AM_V_AR)$(libcli___a_AR) libcli++.a $(libcli___a_OBJECTS) $(libcli___a_LIBADD) + $(AM_V_at)$(RANLIB) libcli++.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/messages.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/only_long.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + +#clitest_SOURCES = clitest.cc + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/cli++/cli++.h b/lib/cli++/cli++.h new file mode 100644 index 0000000..3dfeb14 --- /dev/null +++ b/lib/cli++/cli++.h @@ -0,0 +1,69 @@ +#ifndef VMAILMGR__CLIPP__CLIPP__H__ +#define VMAILMGR__CLIPP__CLIPP__H__ + +typedef bool (*cli_funcptr)(void*); + +struct cli_stringlist +{ + const char* string; + cli_stringlist* next; + + cli_stringlist(const char* s) + : string(s), next(0) + { + } +}; + +struct cli_option +{ + char ch; + const char* name; + enum { flag, counter, integer, string, stringlist, ulong } type; + int flag_value; + void* dataptr; + const char* helpstr; + const char* defaultstr; + + int set(const char* arg); + int parse_long_eq(const char* arg, int as_short); + int parse_long_noeq(const char* arg, int as_short); +}; + +#define CLI_OPTION_END {0, 0, cli_option::flag, 0, 0, 0, 0} + +/* The following are required from the CLI program */ +extern const char* cli_program; +extern const char* cli_help_prefix; +extern const char* cli_help_suffix; +extern const char* cli_args_usage; +extern const int cli_args_min; +extern const int cli_args_max; +extern cli_option cli_options[]; +extern const bool cli_only_long; +extern int cli_main(int argc, char* argv[]); + +/* The following are provided to the CLI program */ +extern const char* argv0; +extern const char* argv0base; +extern const char* argv0dir; +extern void usage(int exit_value, const char* errorstr = 0); +extern int cli_parse_args(int argc, char* argv[]); + +extern void cli_error(int exit_value, + const char*, + const char* = 0, + const char* = 0, + const char* = 0); + +extern void cli_syserror(int exit_value, + const char*, + const char* = 0, + const char* = 0, + const char* = 0); + +extern void cli_warning(const char*, + const char* = 0, + const char* = 0, + const char* = 0); + +#endif diff --git a/lib/cli++/cli++topod.pl b/lib/cli++/cli++topod.pl new file mode 100644 index 0000000..5d2ef13 --- /dev/null +++ b/lib/cli++/cli++topod.pl @@ -0,0 +1,213 @@ +#!/usr/bin/perl + +sub cstr2pod { + local($_) = shift; + s/\\"/"/go; + s/"([^\"]*)"/"C<$1>"/go; + $_; +} + +$section = 1; + +@section_order = ( + 'NAME', + 'SYNOPSIS', + 'DESCRIPTION', + 'OPTIONS', + 'RETURN VALUE', + 'ERRORS', + 'EXAMPLES', + 'ENVIRONMENT', + 'FILES', + 'SEE ALSO', + 'NOTES', + 'CAVEATS', + 'WARNINGS', + 'DIAGNOSTICS', + 'BUGS', + 'RESTRICTIONS', + 'AUTHOR', + 'AUTHORS', + 'HISTORY' + ); + +sub type2word { + my($type) = shift; + return 'INT' if $type eq 'integer'; + return 'UINT' if $type eq 'ulong'; + return 'STR' if $type eq 'string' || $type eq 'stringlist'; + return '' if $type eq 'flag' || $type eq 'counter'; + die "Invalid cli option type '$type'"; +} + +sub add_option { + my($short, $long, $type, $desc) = @_; + + my $s = '[B<'; + my $o = '=item B<'; + if($short) { + $s .= "-$short"; + $o .= "-$short"; + if($type) { + $s .= " $type"; + $o .= " $type"; + } + } + if($short && $long) { + $s .= ">]\n[B<"; + $o .= ">, B<"; + } + if($long) { + $s .= "--$long"; + $o .= "--$long"; + if($type) { + $s .= "=$type"; + $o .= "=$type"; + } + } + $s .= ">]\n"; + $o .= ">\n\n$desc\n\n"; + + $synopsis .= $s; + $options = "=over 8\n\n" unless $options; + $options .= $o; +} + +sub parse_option { + local($_) = shift; + s/^\s*\{\s*//o; + s/\s*\},?\s*/ /o; + + my $short = $1 if s/^'([^\'])',\s*//o; + die "Invalid cli option" unless $short || s/^0,\s*//o; + + my $long = $1 if s/^"([^\"]+)",\s*//o; + die "Invalid cli_option" unless $long || s/^0,\s*//o; + + my $type = $1 if s/^cli_option::(\S+),\s*//o; + die "Invalid cli_option" unless $type; + $type = &type2word($type); + + my $val = $1 if s/^([^,]+),\s*//o; + my $var = $1 if s/^&([^,]+),\s*//o; + + my $desc = cstr2pod($1) if s/^"([^,]+)",\s*//o; + die "Invalid cli_option" unless $desc; + $desc =~ s/\.?$/./o if $desc; + + my $default = $1 if s/^"([^\"]+)"\s+//o; + die "Invalid cli_option" unless $default || s/^0\s+//o; + $desc .= " Defaults to $default." if $default; + + s/\s*\/\/\s*/ /go; + s/^\s*//o; + + add_option($short, $long, $type, $_ || $desc); +} + +sub parse_options { + $synopsis = "B<$program>\n"; + + my $line; + while(<>) { + s/^\s+//o; + s/\s+$//o; + if($line && /^\{/o) { + &parse_option($line); + $line = ""; + } + next if /^\{\s*0\s*\},?/o; + next if /^\{\s*0\s*,\s*\},?/o; + last if /^\s*\};/o; + $line =~ s/$/ $_/; + } + &parse_option($line) if $line; + + $synopsis .= "I<$usage>" if $usage; + $options .= "=back" if $options; + $sections{'SYNOPSIS'} = $synopsis; + $sections{'OPTIONS'} = $options; +} + +sub parse_notes { + my $section; + my $title; + while(<>) { + chomp; + last unless /^$/o || s/^\/\/\s*//o; + if(/^[\sA-Z]+$/o) { + $sections{$title} = $section if $title && $section; + undef $section; + $title = $_; + } else { + $section .= "$_\n"; + } + } + $sections{$title} = $section if $title && $section; +} + +sub parse_header_line { + local($_, $comment) = @_; + if(s/^\s*const\s+char\s*\*\s*cli_(\S+)\s*=\s*//o) { + my $name = $1; + s/;\s*$//o; + s/^\"//; + s/\"$//o; + s/\\n$//o; + s/\\n""/\n/go; + $program = $_ if $name eq 'program'; + $prefix = $_ if $name eq 'help_prefix'; + $usage = $_ if $name eq 'args_usage'; + $suffix = $_ if $name eq 'help_suffix'; + } +} + +sub parse_header { + my $comment = ''; + my $line = ''; + while(<>) { + s/^\s+//o; + s/\s+$//o; + if(s/^.*Copyright\s*\(C\)\s*[\d,]+\s*//o) { + $author = $_; + } else { + last if ($program && $prefix && /^$/o); + next if /^#/o; + $comment .= "$1\n" if s|\s*//\s*(.*)$||o; + $line =~ s/$/\n$_/; + if(/;$/o) { + &parse_header_line($line, $comment); + undef $line; + undef $comment; + } + } + } +} + +sub parse_description { + while(<>) { + s/^\s+//o; + s/\s+$//o; + last if / cli_options\[\]\s*=\s*\{/o; + next unless s/^\/\/\s*//o; + $description .= "$_\n"; + } +} + +&parse_header; +&parse_description; +&parse_options; +&parse_notes; + +$description .= "\n\n$suffix\n" if $suffix; + +$sections{'NAME'} = "$program - $prefix"; +$sections{'DESCRIPTION'} = $description; +$sections{'AUTHORS'} = $author if $author; + +foreach $section (@section_order) { + print "=head1 $section\n\n$sections{$section}\n\n" + if $sections{$section}; +} + +1; diff --git a/lib/cli++/clitest.cc b/lib/cli++/clitest.cc new file mode 100644 index 0000000..97f703d --- /dev/null +++ b/lib/cli++/clitest.cc @@ -0,0 +1,47 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#include <config.h> +#include "cli++.h" +#include "fdbuf/fdbuf.h" + +const char* cli_program = "clitest"; +const char* cli_help_prefix = "Does nothing but set flags\n"; +const char* cli_help_suffix = ""; +const char* cli_args_usage = ""; +const int cli_args_min = 0; +const int cli_args_max = -1; +int o_flag = 0; +int o_int = 0; +char* o_string = "nostring"; +cli_option cli_options[] = { + { 'f', "flag", cli_option::flag, 1, &o_flag, "Sets a flag", 0 }, + { 'i', "int", cli_option::integer, 0, &o_int, "Sets an integer", 0 }, + { 's', "str", cli_option::string, 0, &o_string, "Sets a string", 0}, + {0} }; + +int cli_main(int argc, char* argv[]) +{ + fout << "argv0=" << argv0 << endl + << " argv0dir=" << argv0dir << endl + << " argv0base=" << argv0base << endl; + fout << "The flag is set to " << o_flag << endl; + fout << "The integer is set to " << o_int << endl; + fout << "The string is set to " << o_string << endl; + for(int i = 0; i < argc; i++) + fout << "argv[" << i << "] = '" << argv[i] << "'\n"; + return 0; +} diff --git a/lib/cli++/main.cc b/lib/cli++/main.cc new file mode 100644 index 0000000..83c26e2 --- /dev/null +++ b/lib/cli++/main.cc @@ -0,0 +1,377 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#include <config.h> +#include "ac/time.h" +#include "fdbuf/fdbuf.h" +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include "cli++.h" + +#ifndef HAVE_SRANDOM +void srandom(unsigned int seed); +#endif + +static bool do_show_usage = false; +const char* argv0; +const char* argv0base; +const char* argv0dir; + +static cli_option help_option = { 'h', "help", cli_option::flag, + true, &do_show_usage, + "Display this help and exit", 0 }; + +static cli_option** options; +static unsigned optionc; +static const char* short_options; + +static void build_options() +{ + for(optionc = 0; + cli_options[optionc].ch || cli_options[optionc].name; + optionc++) ; + optionc++; + options = new cli_option*[optionc]; + for(unsigned i = 0; i < optionc-1; i++) + options[i] = &cli_options[i]; + options[optionc-1] = &help_option; + + char* so; + short_options = so = new char[optionc+1]; + for (unsigned i = 0; i < optionc; i++) + if (options[i]->ch != 0) + *so++ = options[i]->ch; + *so = 0; +} + +static inline int max(int a, int b) +{ + return (a>b) ? a : b; +} + +static const char* fill(int i) +{ + static int lastlen = 0; + static char* buf = 0; + if(i > lastlen) { + delete[] buf; + buf = new char[i+1]; + lastlen = i; + } + memset(buf, ' ', i); + buf[i] = 0; + return buf; +} + +static void show_usage() +{ + fout << "usage: " << cli_program << " [flags] " << cli_args_usage << endl; +} + +static int calc_width(const cli_option* o) +{ + int width = (o->ch || !cli_only_long) ? 4 : 2; + if (o->name) { + width += strlen(o->name) + 2 + !cli_only_long; + switch (o->type) { + case cli_option::string: width += 6; break; + case cli_option::integer: width += 4; break; + case cli_option::ulong: width += 4; break; + case cli_option::stringlist: width += 5; break; + case cli_option::flag: break; + case cli_option::counter: break; + } + } + return width; +} + +static int calc_max_width() +{ + // maxwidth is the maximum width of the option text prefix + int maxwidth = 0; + for(unsigned i = 0; i < optionc; i++) + maxwidth = max(maxwidth, calc_width(options[i])); + return maxwidth; +} + +static void show_option(const cli_option* o, int maxwidth) +{ + if(o == &help_option) + fout << '\n'; + fout << " "; + if(o->ch) + fout << '-' << o->ch; + else if (!cli_only_long) + fout << " "; + if (o->ch || !cli_only_long) + fout << (o->ch && o->name ? ", " : " "); + if(o->name) { + const char* extra = ""; + switch(o->type) { + case cli_option::string: extra = "=VALUE"; break; + case cli_option::integer: extra = "=INT"; break; + case cli_option::ulong: extra = "=UNS"; break; + case cli_option::stringlist: extra = "=ITEM"; break; + case cli_option::flag: break; + case cli_option::counter: break; + } + fout << (cli_only_long ? "-" : "--") << o->name << extra + << fill(maxwidth - strlen(o->name) - strlen(extra) - !cli_only_long + - (o->ch || !cli_only_long ? 4 : 0)); + } + else + fout << fill(maxwidth-3); + fout << o->helpstr << '\n'; + if(o->defaultstr) + fout << fill(maxwidth+3) << "(Defaults to " << o->defaultstr << ")\n"; +} + +static void show_help() +{ + if(cli_help_prefix) + fout << cli_help_prefix; + int maxwidth = calc_max_width(); + for(unsigned i = 0; i < optionc; i++) + show_option(options[i], maxwidth); + if(cli_help_suffix) + fout << cli_help_suffix; +} + +void usage(int exit_value, const char* errorstr) +{ + if(errorstr) + ferr << cli_program << ": " << errorstr << endl; + show_usage(); + show_help(); + exit(exit_value); +} + +cli_stringlist* stringlist_append(cli_stringlist* node, const char* newstr) +{ + cli_stringlist* newnode = new cli_stringlist(newstr); + if(node) { + cli_stringlist* head = node; + while(node->next) + node = node->next; + node->next = newnode; + return head; + } + else + return newnode; +} + +int cli_option::set(const char* arg) +{ + char* endptr; + switch(type) { + case flag: + *(int*)dataptr = flag_value; + return 0; + case counter: + *(int*)dataptr += flag_value; + return 0; + case integer: + { + long longresult = strtol(arg, &endptr, 10); + if(*endptr || longresult < INT_MIN || longresult > INT_MAX) { + ferr << argv0 << ": invalid integer: " << arg << endl; + return -1; + } + *(int*)dataptr = (int) longresult; + return 1; + } + case ulong: + *(unsigned long*)dataptr = strtoul(arg, &endptr, 10); + if(*endptr) { + ferr << argv0 << ": invalid unsigned integer: " << arg << endl; + return -1; + } + return 1; + case stringlist: + *(cli_stringlist**)dataptr = + stringlist_append(*(cli_stringlist**)dataptr, arg); + return 1; + default: // string + *(const char**)dataptr = arg; + return 1; + } +} + +static int parse_short(int argc, char* argv[]) +{ + int end = strlen(argv[0]) - 1; + for(int i = 1; i <= end; i++) { + int ch = argv[0][i]; + unsigned j; + for(j = 0; j < optionc; j++) { + cli_option* o = options[j]; + if(o->ch == ch) { + if(o->type != cli_option::flag && + o->type != cli_option::counter) { + if(i < end) { + if(o->set(argv[0]+i+1) != -1) + return 0; + } + else if(argc <= 1) { + ferr << argv0 << ": option -" << o->ch + << " requires a value." << endl; + } + else + if(o->set(argv[1]) != -1) + return 1; + } + else if(o->set(0) != -1) + break; + return -1; + } + } + if(j >= optionc) { + ferr << argv0 << ": unknown option letter -" << argv[0][i] << endl; + return -1; + } + } + return 0; +} + +static void option_error(const cli_option* o, int as_short, const char* text) +{ + ferr << argv0 << ": option "; + if (as_short) + ferr << '-' << o->ch; + else + ferr << (cli_only_long ? "-" : "--") << o->name; + ferr << text << endl; +} + +int cli_option::parse_long_eq(const char* arg, int as_short) +{ + if(type == flag || type == counter) { + option_error(this, as_short, " does not take a value."); + return -1; + } + else + return set(arg)-1; +} + +int cli_option::parse_long_noeq(const char* arg, int as_short) +{ + if(type == flag || type == counter) + return set(0); + else if(arg) + return set(arg); + else { + option_error(this, as_short, " requires a value."); + return -1; + } +} + +static int parse_long(int, char* argv[]) +{ + const char* arg = argv[0]+1; + // Handle both short and long args + if (arg[0] == '-') + ++arg; + for(unsigned j = 0; j < optionc; j++) { + cli_option* o = options[j]; + if(o->name) { + size_t len = strlen(o->name); + if(!memcmp(arg, o->name, len)) { + if(arg[len] == '\0') + return o->parse_long_noeq(argv[1], false); + else if(arg[len] == '=') + return o->parse_long_eq(arg+len+1, false); + } + } + } + ferr << argv0 << ": unknown option string: '" << argv[0] << "'" << endl; + return -1; +} + +static int parse_either(int argc, char* argv[]) +{ + return (strchr(short_options, argv[0][1]) != 0) + ? parse_short(argc, argv) + : parse_long(argc, argv); +} + +int cli_parse_args(int argc, char* argv[]) +{ + int i; + for(i = 1; i < argc; i++) { + const char* arg = argv[i]; + // Stop at the first non-option argument + if(arg[0] != '-') + break; + // Stop after the first "-" or "--" + if(arg[1] == '\0' || + (arg[1] == '-' && arg[2] == '\0')) { + i++; + break; + } + int j = (arg[1] == '-') ? parse_long(argc-i, argv+i) + : cli_only_long ? parse_either(argc-i, argv+i) + : parse_short(argc-i, argv+i); + if(j < 0) + usage(1); + else + i += j; + } + return i; +} + +static void set_argv0(const char* p) +{ + argv0 = p; + static const char* empty = ""; + const char* s = strrchr(p, '/'); + if(s) { + ++s; + argv0base = s; + size_t length = s-p; + char* tmp = new char[length+1]; + memcpy(tmp, p, length); + tmp[length] = 0; + argv0dir = tmp; + } + else { + argv0base = p; + argv0dir = empty; + } +} + +int main(int argc, char* argv[]) +{ + struct timeval tv; + gettimeofday(&tv, 0); + srandom(tv.tv_usec ^ tv.tv_sec); + + set_argv0(argv[0]); + build_options(); + int lastarg = cli_parse_args(argc, argv); + + if(do_show_usage) + usage(0); + + argc -= lastarg; + argv += lastarg; + if(argc < cli_args_min) + usage(1, "Too few command-line arguments"); + if(cli_args_max >= cli_args_min && argc > cli_args_max) + usage(1, "Too many command-line arguments"); + + return cli_main(argc, argv); +} diff --git a/lib/cli++/messages.cc b/lib/cli++/messages.cc new file mode 100644 index 0000000..d9e053d --- /dev/null +++ b/lib/cli++/messages.cc @@ -0,0 +1,68 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#include <errno.h> +#include <config.h> +#include "fdbuf/fdbuf.h" +#include <stdlib.h> +#include <string.h> +#include "cli++.h" + +extern const char* argv0; + +static void cli_msg(const char* prefix, + const char* a, + const char* b, + const char* c, + const char* d, + bool add_error = false) +{ + ferr << cli_program << ": " << prefix << a; + if(b) ferr << b; + if(c) ferr << c; + if(d) ferr << d; + if (add_error) + ferr << ": " << strerror(errno); + ferr << endl; +} + +void cli_error(int exit_value, + const char* a, + const char* b, + const char* c, + const char* d) +{ + cli_msg("Error: ", a, b, c, d, false); + exit(exit_value); +} + +void cli_syserror(int exit_value, + const char* a, + const char* b, + const char* c, + const char* d) +{ + cli_msg("Error: ", a, b, c, d, true); + exit(exit_value); +} + +void cli_warning(const char* a, + const char* b, + const char* c, + const char* d) +{ + cli_msg("Warning: ", a, b, c, d, false); +} diff --git a/lib/cli++/only_long.cc b/lib/cli++/only_long.cc new file mode 100644 index 0000000..3800a25 --- /dev/null +++ b/lib/cli++/only_long.cc @@ -0,0 +1,3 @@ +#include "cli++.h" + +const bool cli_only_long = false; diff --git a/lib/config_path.cc b/lib/config_path.cc new file mode 100644 index 0000000..f758a23 --- /dev/null +++ b/lib/config_path.cc @@ -0,0 +1,58 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include "defines.h" +#include <stdlib.h> +#include "configio.h" +#include "fdbuf/fdbuf.h" + +mystring config_BIN_DIR; +mystring config_CONFIG_DIR; +mystring config_HOME_DIR; +mystring config_PROTOCOLS_DIR; +mystring config_SBIN_DIR; + +static mystring test_prefix; +static bool initialized = false; + +mystring config_path(const char* dflt, const char* testdir, const char* subdir, const char* filename) +{ + if (!initialized) { + // Check if the program is running setuid, to avoid privilege escalation. + if (getuid() == geteuid()) + test_prefix = getenv("NULLMAILER_TEST_PREFIX"); + } + mystring result = test_prefix; + if (!result) + result = dflt; + else { + result += '/'; + result += testdir; + } + result += '/'; + if (subdir) { + result += subdir; + result += '/'; + } + result += filename; + return result; +} diff --git a/lib/config_read.cc b/lib/config_read.cc new file mode 100644 index 0000000..e6c4e77 --- /dev/null +++ b/lib/config_read.cc @@ -0,0 +1,37 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include "defines.h" +#include "configio.h" +#include "fdbuf/fdbuf.h" + +bool config_read(const char* filename, mystring& result) +{ + const mystring fullname = CONFIG_PATH(CONFIG, NULL, filename); + fdibuf in(fullname.c_str()); + if (!in) + return config_syserr(fullname.c_str()); + if(!in.getline(result)) + return false; + result = result.strip(); + return result.length() > 0; +} diff --git a/lib/config_readint.cc b/lib/config_readint.cc new file mode 100644 index 0000000..c2b0eb9 --- /dev/null +++ b/lib/config_readint.cc @@ -0,0 +1,38 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include <stdlib.h> +#include <limits.h> +#include "defines.h" +#include "configio.h" +#include "fdbuf/fdbuf.h" + +bool config_readint(const char* filename, int& result) +{ + mystring tmp; + if(!config_read(filename, tmp)) + return false; + char* endptr; + long longresult = strtol(tmp.c_str(), &endptr, 10); + result = (int) longresult; + return endptr > tmp.c_str() && longresult >= INT_MIN && longresult <= INT_MAX; +} diff --git a/lib/config_readlist.cc b/lib/config_readlist.cc new file mode 100644 index 0000000..2b49d5d --- /dev/null +++ b/lib/config_readlist.cc @@ -0,0 +1,43 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include "defines.h" +#include "configio.h" +#include "fdbuf/fdbuf.h" + +bool config_readlist(const char* filename, list<mystring>& result) +{ + const mystring fullname = CONFIG_PATH(CONFIG, NULL, filename); + fdibuf in(fullname.c_str()); + if(!in) + return config_syserr(fullname.c_str()); + mystring tmp; + bool nonempty = false; + while(in.getline(tmp)) { + tmp = tmp.strip(); + if(tmp[0] != '#' && tmp.length() > 0) { + result.append(tmp); + nonempty = true; + } + } + return nonempty; +} diff --git a/lib/config_syserr.cc b/lib/config_syserr.cc new file mode 100644 index 0000000..9dd70c0 --- /dev/null +++ b/lib/config_syserr.cc @@ -0,0 +1,33 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include <errno.h> +#include "config.h" +#include "errcodes.h" +#include "configio.h" +#include "cli++/cli++.h" + +bool config_syserr(const char* filename) +{ + if (errno != ENOENT) + cli_syserror(ERR_CONFIG, "Could not read config file \"", filename, "\""); + return false; +} diff --git a/lib/configio.h b/lib/configio.h new file mode 100644 index 0000000..c176ae8 --- /dev/null +++ b/lib/configio.h @@ -0,0 +1,15 @@ +#ifndef NULLMAILER__CONFIGIO__H__ +#define NULLMAILER__CONFIGIO__H__ + +#include "mystring/mystring.h" +#include "list.h" + +mystring config_path(const char* dflt, const char* testdir, const char* subdir, const char* filename); +#define CONFIG_PATH(NAME, SUBDIR, FILENAME) config_path(NAME##_DIR, NAME##_TEST_DIR, SUBDIR, FILENAME) + +bool config_read(const char* filename, mystring& result); +bool config_readlist(const char* filename, list<mystring>& result); +bool config_readint(const char* filename, int& result); +bool config_syserr(const char* filename); + +#endif // NULLMAILER__CONFIGIO__H__ diff --git a/lib/connect.h b/lib/connect.h new file mode 100644 index 0000000..d3354b0 --- /dev/null +++ b/lib/connect.h @@ -0,0 +1,6 @@ +#ifndef NULLMAILER_CONNECT__H__ +#define NULLMAILER_CONNECT__H__ + +extern int tcpconnect(const char* hostname, int port, const char* source); + +#endif // NULLMAILER_CONNECT__H__ diff --git a/lib/defines.h b/lib/defines.h new file mode 100644 index 0000000..e7c4427 --- /dev/null +++ b/lib/defines.h @@ -0,0 +1,16 @@ +#ifndef NULLMAILER__DEFINES__H__ +#define NULLMAILER__DEFINES__H__ + +extern const char QUEUE_DIR[]; +extern const char CONFIG_DIR[]; +extern const char PROTOCOLS_DIR[]; +extern const char BIN_DIR[]; +extern const char SBIN_DIR[]; + +#define QUEUE_TEST_DIR "queue" +#define CONFIG_TEST_DIR "conf" +#define PROTOCOLS_TEST_DIR "protocols" +#define BIN_TEST_DIR "bin" +#define SBIN_TEST_DIR "sbin" + +#endif /* NULLMAILER__DEFINES__H__ */ diff --git a/lib/errcodes.cc b/lib/errcodes.cc new file mode 100644 index 0000000..84b9f76 --- /dev/null +++ b/lib/errcodes.cc @@ -0,0 +1,51 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "errcodes.h" + +const char* errorstr(int code) +{ + switch (code) { + case 0: return "No error"; + case ERR_HOST_NOT_FOUND: return "Host not found"; + case ERR_NO_ADDRESS: return "Host has no address"; + case ERR_GHBN_FATAL: return "Fatal error in gethostbyname"; + case ERR_GHBN_TEMP: return "Temporary error in gethostbyname"; + case ERR_SOCKET: return "Socket failed"; + case ERR_CONN_REFUSED: return "Connection refused"; + case ERR_CONN_TIMEDOUT: return "Connection timed out"; + case ERR_CONN_UNREACHABLE: return "Host or network unreachable"; + case ERR_CONN_FAILED: return "Connection failed"; + case ERR_PROTO: return "Protocol error"; + case ERR_MSG_OPEN: return "Could not open message"; + case ERR_MSG_READ: return "Could not read message"; + case ERR_MSG_WRITE: return "Could not write message"; + case ERR_EXEC_FAILED: return "Could not exec program"; + case ERR_MSG_TEMPFAIL: return "Temporary error in sending the message"; + case ERR_CONFIG: return "Could not read config files"; + case ERR_MSG_REFUSED: return "Server refused the message"; + case ERR_MSG_PERMFAIL: return "Permanent error in sending the message"; + case ERR_BIND_FAILED: return "Failed to bind source address"; + } + return (code & ERR_PERMANENT_FLAG) + ? "Unspecified permanent error" + : "Unspecified temporary error"; +} diff --git a/lib/errcodes.h b/lib/errcodes.h new file mode 100644 index 0000000..94564ee --- /dev/null +++ b/lib/errcodes.h @@ -0,0 +1,33 @@ +#ifndef NULLMAILER__ERRCODES__H__ +#define NULLMAILER__ERRCODES__H__ + +// Temporary errors +#define ERR_USAGE 1 // Invalid command-line arguments +#define ERR_HOST_NOT_FOUND 2 // gethostbyname failed with HOST_NOT_FOUND +#define ERR_NO_ADDRESS 3 // gethostbyname failed with NO_ADDRESS +#define ERR_GHBN_TEMP 5 // gethostbyname failed with TRY_AGAIN +#define ERR_SOCKET 6 // socket failed +#define ERR_CONN_REFUSED 7 // connect failed with ECONNREFUSED +#define ERR_CONN_TIMEDOUT 8 // connect failed with ETIMEDOUT +#define ERR_CONN_UNREACHABLE 9 // connect failed with ENETUNREACH +#define ERR_CONN_FAILED 10 // connect failed +#define ERR_PROTO 11 // unexpected result from server +#define ERR_MSG_OPEN 12 // could not open the message +#define ERR_MSG_READ 13 // reading the message failed +#define ERR_MSG_WRITE 14 // writing the message failed +#define ERR_EXEC_FAILED 15 // executing a program failed +#define ERR_MSG_TEMPFAIL 16 // server temporarily failed to receive +#define ERR_UNKNOWN 17 // Arbitrary error code +#define ERR_CONFIG 18 // Error reading a config file +#define ERR_BIND_FAILED 19 // Failed to bind source address + +// Permanent errors +#define ERR_GHBN_FATAL 33 // gethostbyname failed with NO_RECOVERY +#define ERR_MSG_REFUSED 34 // server refused the message +#define ERR_MSG_PERMFAIL 35 // server permanently failed to receive + +#define ERR_PERMANENT_FLAG 32 + +extern const char* errorstr(int); + +#endif // NULLMAILER__ERRCODES__H__ diff --git a/lib/fdbuf/ChangeLog b/lib/fdbuf/ChangeLog new file mode 100644 index 0000000..ba96ad5 --- /dev/null +++ b/lib/fdbuf/ChangeLog @@ -0,0 +1,161 @@ +2000-08-22 Bruce Guenter <bruce@bruce-guenter.dyndns.org> + + * Added the missing accessor for the internal "errnum" data member + to the fdibuf and fdobuf classes. + +2000-08-10 Bruce Guenter <bruce@bruce-guenter.dyndns.org> + + * fdibuf.cc (read_large): Fixed a bug in the increment of data. + + * fdibuf_mystring.cc (getline): Reduced some of the expressions + into variables. + +2000-04-08 Bruce Guenter <bguenter@bguenter.pointsnorth.com> + + * fdibuf.cc (read_large): Fixed bug: count needed to be + incremented after reading data in. + +2000-04-07 Bruce Guenter <bguenter@bguenter.pointsnorth.com> + + * fdobuf_signed.cc (operator<<): Immediately output a '-' for + negative numbers rather than storing a negative flag for later. + + * fdobuf_unsigned.cc (operator<<): Moved the integer versions of + this operator into their own modules. + + * fdobuf_seek.cc (seek): Moved this routine out of fdobuf.cc + + * fdibuf.cc (read_large): Added this routine to read in a chunk of + data larger than the size of the buffer. + +2000-04-06 Bruce Guenter <bguenter@bguenter.pointsnorth.com> + + * fdibuf_netstring.cc (getnetstring): Moved this routine into its + own source file. + + * fdobuf.cc (write_large): Added this routine to write out a chunk + of data larger than the size of the buffer, to avoid doing extra + copies. + (write): Removed an extraneous code segment. + + * fdobuf.h: Moved the fdobuf declarations here. + + * fdibuf.h: Moved the fdibuf declarations here. + + * fdbuf.h: Removed extraneous fdobuf declaration. + +1999-07-08 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdobuf.cc (write): Optimized this routine better for the case + where the amount of data to be written will fit inside the buffer. + +1999-07-05 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdbuf.h (fdobuf,fdibuf): Made some of the routines here virtual + in order to extend it properly. + Added "tell()" operations to both fdibuf and fdobuf to indicate + the current logical read/write point. + +1999-07-04 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdobuf_chownmod.cc: Added two new routines chown and chmod, + which operate directly on the open fd. + +1999-06-30 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdibuf_mystring.cc (getline): Make this routine return the + number of bytes actually read, including the delimiter, even + though the delimiter is not added to the returned string. + +1999-06-29 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdibuf.cc (fdibuf): Added a 'seekfwd' function to seek forwards + "o" bytes. + + * fdibuf_mystring.cc (getline): Added locking and set the count + properly. + +1999-06-28 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdibuf.cc (get): Make sure count is set for get. + +1999-06-06 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdbuf.cc (fdbuf): Fixed long-standing bug -- I forgot to delete + the buffer in the destructor. + (close): Modified the code to ensure that the fd is not closed + twice (as would happen when destructing the fdbuf). + +1999-05-31 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdobuf.cc: Redefined flush as nflush; added sync code to nflush; + made flush and sync call nflush; added mutex lock calls to all + public methods. + + * fdibuf.cc: Added mutex lock calls to all public methods. + + * fdbuf.cc: Added debugging implementations of lock() and unlock() + mutex operators (to be removed before real use). + +1999-05-28 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdobuf.cc (fdobuf): Fixed missing initialization of bufpos in + one of the two constructors. + +1999-05-01 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdobuf.cc (fdobuf): Added an optional "mode" parameter which + defaults to 0666, which is the permissions for the new file. + (sync): Wrote this function to fsync the file descriptor. + +1999-04-27 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdbuf.h (fdobuf): Removed definition for sync and nonblock mode, + as they won't be handled correctly in the writing code. + +1999-04-03 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdobuf.cc (operator<<): Wrote an operator for signed and + unsigned longs, with overloaded functions for ints and shorts that + promote the parameters to longs. + (write): Wrote a write routine specifically for a single + character. + +1999-04-01 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdobuf.cc: Fixed handling of seek by adding a "bufpos" indicator + that points to the current position in the buffer at which writes + should go. buflength is effectively the maximum value of bufpos + between flushes. + + * fdibuf.cc (get): Renamed getchar to get (to be potentially + overloaded with other types). + + * fdbuf.h (fdbuf): Removed a bunch of write methods and replaced + them with "operator<<", with similar capability to iostreams + methods of the same names. + + * fdobuf.cc (endl): Wrote this manipulator to write an end-of-line + and flush the buffer. + +1999-03-31 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * fdobuf_mystring.cc: Moved all the mystring-specific code from + fdobuf.cc into this module to lessen link problems. + + * fdibuf_mystring.cc: Moved all the mystring-specific code from + fdibuf.cc into this module to lessen link problems. + + * fdobuf.cc (seek): Wrote this seek routine to allow movement in + an output file buffer. + + * fdibuf.cc (seek): Generalized the rewind routine to allow + arbitrary seeks. It also checks to see if the seek point is + within the current buffer and if so just repositions its + pointers. + + * fdbuf.h: If BUFSIZE is not defined, set it here to 4096. + (class fdbuf ): Rename length, start, and size to buflength, + bufstart, and bufsize. Add a new field "offset" to indicate the + current file seek offset. + diff --git a/lib/fdbuf/Makefile.am b/lib/fdbuf/Makefile.am new file mode 100644 index 0000000..152d634 --- /dev/null +++ b/lib/fdbuf/Makefile.am @@ -0,0 +1,29 @@ +noinst_LIBRARIES = libfdbuf.a +AM_CPPFLAGS = -I$(top_srcdir)/lib + +if FDBUF_NO_MYSTRING +mystring_sources = +else +mystring_sources = fdibuf_mystring.cc fdibuf_netstring.cc +endif + +if TLS +tls_sources = tlsibuf.h tlsibuf.cc tlsobuf.h tlsobuf.cc +else +tls_sources = +endif + +libfdbuf_a_SOURCES = \ + fdbuf.h \ + fdbuf.cc \ + fdbuf_copy.cc \ + fdibuf.h \ + fdibuf.cc \ + fdobuf.h \ + fdobuf.cc \ + fdobuf_chownmod.cc \ + fdobuf_seek.cc \ + fdobuf_signed.cc \ + fdobuf_unsigned.cc \ + $(tls_sources) \ + $(mystring_sources) diff --git a/lib/fdbuf/Makefile.in b/lib/fdbuf/Makefile.in new file mode 100644 index 0000000..8c84ce0 --- /dev/null +++ b/lib/fdbuf/Makefile.in @@ -0,0 +1,587 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = lib/fdbuf +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libfdbuf_a_AR = $(AR) $(ARFLAGS) +libfdbuf_a_LIBADD = +am__libfdbuf_a_SOURCES_DIST = fdbuf.h fdbuf.cc fdbuf_copy.cc fdibuf.h \ + fdibuf.cc fdobuf.h fdobuf.cc fdobuf_chownmod.cc fdobuf_seek.cc \ + fdobuf_signed.cc fdobuf_unsigned.cc tlsibuf.h tlsibuf.cc \ + tlsobuf.h tlsobuf.cc fdibuf_mystring.cc fdibuf_netstring.cc +@TLS_TRUE@am__objects_1 = tlsibuf.$(OBJEXT) tlsobuf.$(OBJEXT) +@FDBUF_NO_MYSTRING_FALSE@am__objects_2 = fdibuf_mystring.$(OBJEXT) \ +@FDBUF_NO_MYSTRING_FALSE@ fdibuf_netstring.$(OBJEXT) +am_libfdbuf_a_OBJECTS = fdbuf.$(OBJEXT) fdbuf_copy.$(OBJEXT) \ + fdibuf.$(OBJEXT) fdobuf.$(OBJEXT) fdobuf_chownmod.$(OBJEXT) \ + fdobuf_seek.$(OBJEXT) fdobuf_signed.$(OBJEXT) \ + fdobuf_unsigned.$(OBJEXT) $(am__objects_1) $(am__objects_2) +libfdbuf_a_OBJECTS = $(am_libfdbuf_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libfdbuf_a_SOURCES) +DIST_SOURCES = $(am__libfdbuf_a_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ + ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HAVE_GETADDRINFO = @HAVE_GETADDRINFO@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RM = @RM@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libfdbuf.a +AM_CPPFLAGS = -I$(top_srcdir)/lib +@FDBUF_NO_MYSTRING_FALSE@mystring_sources = fdibuf_mystring.cc fdibuf_netstring.cc +@FDBUF_NO_MYSTRING_TRUE@mystring_sources = +@TLS_FALSE@tls_sources = +@TLS_TRUE@tls_sources = tlsibuf.h tlsibuf.cc tlsobuf.h tlsobuf.cc +libfdbuf_a_SOURCES = \ + fdbuf.h \ + fdbuf.cc \ + fdbuf_copy.cc \ + fdibuf.h \ + fdibuf.cc \ + fdobuf.h \ + fdobuf.cc \ + fdobuf_chownmod.cc \ + fdobuf_seek.cc \ + fdobuf_signed.cc \ + fdobuf_unsigned.cc \ + $(tls_sources) \ + $(mystring_sources) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/fdbuf/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu lib/fdbuf/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libfdbuf.a: $(libfdbuf_a_OBJECTS) $(libfdbuf_a_DEPENDENCIES) $(EXTRA_libfdbuf_a_DEPENDENCIES) + $(AM_V_at)-rm -f libfdbuf.a + $(AM_V_AR)$(libfdbuf_a_AR) libfdbuf.a $(libfdbuf_a_OBJECTS) $(libfdbuf_a_LIBADD) + $(AM_V_at)$(RANLIB) libfdbuf.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdbuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdbuf_copy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdibuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdibuf_mystring.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdibuf_netstring.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdobuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdobuf_chownmod.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdobuf_seek.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdobuf_signed.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdobuf_unsigned.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlsibuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlsobuf.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/fdbuf/fdbuf.cc b/lib/fdbuf/fdbuf.cc new file mode 100644 index 0000000..2b3d65a --- /dev/null +++ b/lib/fdbuf/fdbuf.cc @@ -0,0 +1,107 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "fdbuf.h" +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +/////////////////////////////////////////////////////////////////////////////// +// Class fdbuf +/////////////////////////////////////////////////////////////////////////////// +fdbuf::fdbuf(int fdesc, bool dc, unsigned bufsz) + : buf(new char[bufsz]), + buflength(0), + bufstart(0), + offset(0), + errnum(0), + flags(0), + bufsize(bufsz), + fd(fdesc), + do_close(dc) +{ + if(!buf) { + flags = flag_error; + errnum = errno; + } + if(fdesc < 0) + flags |= flag_closed; +#ifdef _REENTRANT + pthread_mutex_t tmp = PTHREAD_MUTEX_INITIALIZER; + mutex = tmp; + pthread_mutex_init(&mutex, 0); +#else +#ifdef FDBUF_MUTEX_DEBUG + mutex_count = 0; +#endif +#endif +} + +fdbuf::~fdbuf() +{ + close(); +#ifdef _REENTRANT + pthread_mutex_destroy(&mutex); +#endif + delete buf; +} + +bool fdbuf::error() const +{ + return flags & flag_error; +} + +bool fdbuf::closed() const +{ + return flags & flag_closed; +} + +bool fdbuf::close() +{ + if(do_close && fd >= 0 && !(flags & flag_closed)) { + if(::close(fd) == -1) { + errnum = errno; + flags |= flag_error; + return false; + } + flags |= flag_closed; + } + return true; +} + +#if defined(FDBUF_MUTEX_DEBUG) && !defined(_REENTRANT) +{ + int* null = 0; + (*null)++; + kill(getpid(), 9); +} + +// Debugging code +void fdbuf::lock() +{ + if(mutex) + abort(); + ++mutex; +} + +void fdbuf::unlock() +{ + if(mutex != 1) + abort(); + --mutex; +} +#endif diff --git a/lib/fdbuf/fdbuf.h b/lib/fdbuf/fdbuf.h new file mode 100644 index 0000000..d11682f --- /dev/null +++ b/lib/fdbuf/fdbuf.h @@ -0,0 +1,83 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef FDBUF__H__ +#define FDBUF__H__ + +#include "config.h" +#include <string.h> +#include <fcntl.h> +#include <unistd.h> + +#ifdef _REENTRANT +#include <pthread.h> +#endif + +#ifndef FDBUF_SIZE +#define FDBUF_SIZE 4096 +#endif + +class mystring; + +class fdbuf +{ +public: + enum flagbits { flag_eof=1, flag_error=2, flag_closed=4 }; + + fdbuf(int fdesc, bool dc, unsigned bufsz = FDBUF_SIZE); + ~fdbuf(); + bool error() const; + bool closed() const; + bool close(); +#ifdef _REENTRANT + void lock() { pthread_mutex_lock(&mutex); } + void unlock() { pthread_mutex_unlock(&mutex); } +#else +#ifdef FDBUF_MUTEX_DEBUG + void lock(); + void unlock(); +#else + void lock() { } + void unlock() { } +#endif +#endif +protected: + char* const buf; + unsigned buflength; // Length of the data in the buffer + unsigned bufstart; // Start of the data in the buffer + unsigned offset; // Current file read/write offset + int errnum; // Saved error flag + unsigned flags; // Status flags + + const unsigned bufsize; // Total buffer size + const int fd; + const bool do_close; // True to close on destructor + +#ifdef _REENTRANT + pthread_mutex_t mutex; +#else +#ifdef FDBUF_MUTEX_DEBUG + unsigned mutex; +#endif +#endif +}; + +bool fdbuf_copy(class fdibuf&, class fdobuf&, bool noflush = false); + +#include "fdbuf/fdibuf.h" +#include "fdbuf/fdobuf.h" + +#endif // FDBUF__H__ diff --git a/lib/fdbuf/fdbuf_copy.cc b/lib/fdbuf/fdbuf_copy.cc new file mode 100644 index 0000000..a31ab0b --- /dev/null +++ b/lib/fdbuf/fdbuf_copy.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "fdbuf.h" + +/////////////////////////////////////////////////////////////////////////////// +// Other routines +/////////////////////////////////////////////////////////////////////////////// +bool fdbuf_copy(fdibuf& in, fdobuf& out, bool noflush) +{ + if(in.eof()) + return true; + if(!in || !out) + return false; + do { + char buf[FDBUF_SIZE]; + if(!in.read(buf, FDBUF_SIZE) && in.last_count() == 0) + break; + if(!out.write(buf, in.last_count()) && out.last_count() < in.last_count()) + return false; + } while(!in.eof()); + if(!noflush && !out.flush()) + return false; + return in.eof(); +} diff --git a/lib/fdbuf/fdibuf.cc b/lib/fdbuf/fdibuf.cc new file mode 100644 index 0000000..205d63c --- /dev/null +++ b/lib/fdbuf/fdibuf.cc @@ -0,0 +1,197 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "fdbuf.h" +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +/////////////////////////////////////////////////////////////////////////////// +// Class fdibuf +/////////////////////////////////////////////////////////////////////////////// +fdibuf::fdibuf(int fdesc, bool dc, unsigned bufsz) + : fdbuf(fdesc, dc, bufsz) +{ +} + +fdibuf::fdibuf(const char* filename, unsigned bufsz) + : fdbuf(open(filename, O_RDONLY), true, bufsz) +{ + if(fd == -1) { + flags = flag_error; + errnum = errno; + } +} + +fdibuf::~fdibuf() +{ +} + +bool fdibuf::eof() const +{ + return (flags & flag_eof) && (bufstart >= buflength); +} + +bool fdibuf::operator!() const +{ + return eof() || error() || closed(); +} + +// refill is protected -- no locking +bool fdibuf::refill() +{ + if(flags) + return false; + if(bufstart != 0) { + if(bufstart < buflength) { + buflength -= bufstart; + memcpy(buf, buf+bufstart, buflength); + } else + buflength = 0; + bufstart = 0; + } + unsigned oldbuflength = buflength; + if(buflength < bufsize) { + ssize_t red = _read(buf+buflength, bufsize-buflength); + if(red < 0) { + errnum = errno; + flags |= flag_error; + } + else if(red == 0) + flags |= flag_eof; + else { + buflength += red; + offset += red; + } + } + return buflength > oldbuflength; +} + +bool fdibuf::get(char& ch) +{ + lock(); + count = 0; + if(bufstart >= buflength) + refill(); + bool r = true; + if(eof() || error()) + r = false; + else { + ch = buf[bufstart++]; + count = 1; + } + unlock(); + return r; +} + +bool fdibuf::read_large(char* data, unsigned datalen) +{ + lock(); + count = 0; + + // If there's any content in the buffer, memcpy it out first. + unsigned len = buflength - bufstart; + if(len > datalen) + len = datalen; + memcpy(data, buf+bufstart, len); + data += len; + datalen -= len; + bufstart += len; + count += len; + + // After the buffer is empty and there's still data to read, + // read it straight from the fd instead of copying it through the buffer. + while(datalen > 0) { + ssize_t red = _read(data, datalen); + if(red < 0) { + errnum = errno; + flags |= flag_error; + break; + } + else if(red == 0) { + flags |= flag_eof; + break; + } + data += red; + datalen -= red; + offset += red; + count += red; + } + unlock(); + return datalen == 0; +} + +bool fdibuf::read(char* data, unsigned datalen) +{ + if(datalen >= bufsize) + return read_large(data, datalen); + lock(); + count = 0; + char* ptr = data; + while(datalen && !eof()) { + if(bufstart >= buflength) + refill(); + unsigned len = buflength-bufstart; + if(len > datalen) + len = datalen; + memcpy(ptr, buf+bufstart, len); + bufstart += len; + datalen -= len; + ptr += len; + count += len; + } + unlock(); + return !datalen; +} + +bool fdibuf::seek(unsigned o) +{ + lock(); + unsigned buf_start = offset - buflength; + if(o >= buf_start && o < offset) { + bufstart = o - buf_start; + } + else { + if(lseek(fd, o, SEEK_SET) != (off_t)o) { + errnum = errno; + flags |= flag_error; + unlock(); + return false; + } + offset = o; + buflength = bufstart = 0; + } + count = 0; + flags &= ~flag_eof; + unlock(); + return true; +} + +bool fdibuf::seekfwd(unsigned o) +{ + return seek(tell() + o); +} + +ssize_t fdibuf::_read(char* buf, ssize_t len) +{ + return ::read(fd, buf, len); +} + +/////////////////////////////////////////////////////////////////////////////// +// Globals +/////////////////////////////////////////////////////////////////////////////// +fdibuf fin(0); diff --git a/lib/fdbuf/fdibuf.h b/lib/fdbuf/fdibuf.h new file mode 100644 index 0000000..8906b8c --- /dev/null +++ b/lib/fdbuf/fdibuf.h @@ -0,0 +1,53 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef FDBUF__FDIBUF__H__ +#define FDBUF__FDIBUF__H__ + +#include "fdbuf.h" + +class fdibuf : protected fdbuf +{ +public: + fdibuf(const char* filename, unsigned bufsz = FDBUF_SIZE); + fdibuf(int fdesc, bool dc = false, unsigned bufsz = FDBUF_SIZE); + virtual ~fdibuf(); + bool close() { lock(); bool r = fdbuf::close(); unlock(); return r; } + bool eof() const; + bool operator!() const ; + operator bool() const { return !operator!(); } + virtual bool get(char& ch); + virtual bool getline(mystring& out, char terminator = '\n'); + virtual bool getnetstring(mystring& out); + virtual bool read(char*, unsigned); + virtual bool read_large(char*, unsigned); + bool read(unsigned char* b, unsigned l) { return read((char*)b, l); } + bool read(signed char* b, unsigned l) { return read((char*)b, l); } + unsigned last_count() { return count; } + bool seek(unsigned o); + bool seekfwd(unsigned o); + bool rewind() { return seek(0); } + unsigned tell() const { return offset-buflength+bufstart; } + int error_number() const { return errnum; } +protected: + unsigned count; // Number of bytes read by last operation + bool refill(); + virtual ssize_t _read(char*, ssize_t); +}; + +extern fdibuf fin; + +#endif // FDBUF__FDIBUF__H__ diff --git a/lib/fdbuf/fdibuf_mystring.cc b/lib/fdbuf/fdibuf_mystring.cc new file mode 100644 index 0000000..3b40bdc --- /dev/null +++ b/lib/fdbuf/fdibuf_mystring.cc @@ -0,0 +1,52 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include <string.h> +#include "fdbuf.h" +#include "mystring/mystring.h" + +bool fdibuf::getline(mystring& out, char terminator) +{ + lock(); + count = 0; + if(bufstart >= buflength) + refill(); + if(eof() || error()) { + unlock(); + return false; + } + out = ""; + while(!eof() && !error()) { + char* ptr = buf+bufstart; + unsigned bufleft = buflength - bufstart; + const char* end = (const char*)memchr(ptr, terminator, bufleft); + if(!end) { + out += mystring(ptr, bufleft); + bufstart = buflength; + count += bufleft; + refill(); + } + else { + unsigned copylen = end - ptr; + out += mystring(ptr, copylen); + bufstart += copylen+1; + count += copylen+1; + break; + } + } + unlock(); + return true; +} diff --git a/lib/fdbuf/fdibuf_netstring.cc b/lib/fdbuf/fdibuf_netstring.cc new file mode 100644 index 0000000..5f16004 --- /dev/null +++ b/lib/fdbuf/fdibuf_netstring.cc @@ -0,0 +1,41 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include <string.h> +#include "fdbuf.h" +#include "mystring/mystring.h" + +bool fdibuf::getnetstring(mystring& out) +{ + // Read in the size + char ch; + unsigned long size = 0; + for(;;) { + if(!get(ch)) + return false; + if(ch == ':') + break; + else if(ch >= '0' && ch <= '9') + size = size*10 + (ch-'0'); + else + return false; + } + char tmp[size]; + if(!read(tmp, size) || !get(ch) || ch != ',') + return false; + out = mystring(tmp, size); + return true; +} diff --git a/lib/fdbuf/fdobuf.cc b/lib/fdbuf/fdobuf.cc new file mode 100644 index 0000000..e1a6031 --- /dev/null +++ b/lib/fdbuf/fdobuf.cc @@ -0,0 +1,214 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "fdbuf.h" +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +/////////////////////////////////////////////////////////////////////////////// +// Globals +/////////////////////////////////////////////////////////////////////////////// +fdobuf fout(1); +fdobuf ferr(2); + +/////////////////////////////////////////////////////////////////////////////// +// Class fdobuf +/////////////////////////////////////////////////////////////////////////////// +fdobuf::fdobuf(int fdesc, bool dc, unsigned bufsz) + : fdbuf(fdesc, dc, bufsz), + bufpos(0) +{ +} + +fdobuf::fdobuf(const char* filename, int f, int mode, unsigned bufsz) + : fdbuf(open(filename, O_WRONLY | f, mode), true, bufsz), + bufpos(0) +{ + if(fd == -1) { + flags = flag_error; + errnum = errno; + } +} + +fdobuf::~fdobuf() +{ + flush(); +} + +bool fdobuf::close() +{ + if(!flush()) + return false; + lock(); + bool r = fdbuf::close(); + unlock(); + return r; +} + +bool fdobuf::operator!() const +{ + return error() || closed(); +} + +bool fdobuf::nflush(bool withsync) +{ + if(flags) + return false; + while(bufstart < buflength) { + ssize_t written = _write(buf+bufstart, buflength-bufstart); + if(written < 0) { + flags |= flag_error; + errnum = errno; + return false; + } + else { + bufstart += written; + offset += written; + } + } + buflength = 0; + bufstart = 0; + bufpos = 0; + if(withsync && (fsync(fd) == -1)) { + flags |= flag_error; + errnum = errno; + return false; + } + return true; +} + +bool fdobuf::flush() +{ + lock(); + bool r = nflush(false); + unlock(); + return r; +} + +bool fdobuf::sync() +{ + lock(); + bool r = nflush(true); + unlock(); + return r; +} + +bool fdobuf::write(char ch) +{ + if(flags) + return false; + + lock(); + count = 0; + buf[bufpos++] = ch; + //if(buflength >= bufsize && !nflush(false)) { + // unlock(); + // return false; + //} + if(bufpos >= buflength) + buflength = bufpos; + if(buflength >= bufsize && !nflush(false)) { + unlock(); + return false; + } + count = 1; + unlock(); + return true; +} + +bool fdobuf::write_large(const char* data, unsigned datalen) +{ + if(flags) + return false; + + lock(); + count = 0; + + if(!nflush(false)) { + unlock(); + return false; + } + + while(datalen > 0) { + ssize_t written = _write(data, datalen); + if(written < 0) { + flags |= flag_error; + errnum = errno; + unlock(); + return false; + } + datalen -= written; + data += written; + offset += written; + count += written; + } + unlock(); + return true; +} + +bool fdobuf::write(const char* data, unsigned datalen) +{ + if(datalen >= bufsize) + return write_large(data, datalen); + + if(flags) + return false; + + lock(); + const char* ptr = data; + count = 0; + // Amount is the number of bytes available in the buffer + unsigned amount = bufsize-bufpos; + while(datalen >= amount) { + // If we get here, this copy will completely fill the buffer, + // requiring a flush + memcpy(buf+bufpos, ptr, amount); + bufpos = bufsize; + buflength = bufsize; + datalen -= amount; + ptr += amount; + if(!nflush(false)) { + unlock(); + return false; + } + count += amount; + amount = bufsize-bufpos; + } + // At this point, the remaining data will fit into the buffer + memcpy(buf+bufpos, ptr, datalen); + count += datalen; + bufpos += datalen; + if(bufpos > buflength) buflength = bufpos; + unlock(); + return true; +} + +ssize_t fdobuf::_write(const char* buf, ssize_t len) +{ + return ::write(fd, buf, len); +} + +/////////////////////////////////////////////////////////////////////////////// +// Manipulators +/////////////////////////////////////////////////////////////////////////////// +fdobuf& endl(fdobuf& fd) +{ + fd.write("\n", 1); + fd.flush(); + return fd; +} diff --git a/lib/fdbuf/fdobuf.h b/lib/fdbuf/fdobuf.h new file mode 100644 index 0000000..f59f815 --- /dev/null +++ b/lib/fdbuf/fdobuf.h @@ -0,0 +1,92 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef FDBUF__FDOBUF__H__ +#define FDBUF__FDOBUF__H__ + +#include "fdbuf.h" + +class fdobuf : protected fdbuf +{ +public: + enum openflags { create=O_CREAT, + excl=O_EXCL, + trunc=O_TRUNC, + append=O_APPEND }; + + fdobuf(const char* filename, int, int mode = 0666, + unsigned bufsz = FDBUF_SIZE); + fdobuf(int fdesc, bool dc=false, unsigned bufsz = FDBUF_SIZE); + virtual ~fdobuf(); + bool close(); + bool operator!() const; + operator bool() const + { + return !operator!(); + } + bool flush(); + bool sync(); + virtual bool write(char); + bool write(unsigned char c) { return write((char)c); } + bool write(signed char c) { return write((char)c); } + virtual bool write(const char*, unsigned); + bool write(const unsigned char* b, unsigned l) { return write((char*)b, l); } + bool write(const signed char* b, unsigned l) { return write((char*)b, l); } + virtual bool write_large(const char*, unsigned); + unsigned last_count() { return count; } + bool seek(unsigned o); + bool rewind() { return seek(0); } + unsigned tell() const { return offset + bufpos; } + + bool chown(uid_t, gid_t) const; + bool chmod(mode_t) const; + + fdobuf& operator<<(const char* str) + { + write(str, strlen(str)); + return *this; + } + fdobuf& operator<<(char ch) + { + write(ch); + return *this; + } + fdobuf& operator<<(fdobuf& (*manip)(fdobuf&)) + { + return manip(*this); + } + fdobuf& operator<<(unsigned long); + fdobuf& operator<<(signed long); + fdobuf& operator<<(unsigned i) { return operator<<((unsigned long)i); } + fdobuf& operator<<(signed i) { return operator<<((signed long)i); } + fdobuf& operator<<(unsigned short i) { return operator<<((unsigned long)i); } + fdobuf& operator<<(signed short i) { return operator<<((signed long)i); } + + int error_number() const { return errnum; } +protected: + virtual bool nflush(bool withsync); + virtual ssize_t _write(const char* buf, ssize_t len); + + unsigned bufpos; // Current write position in the buffer + unsigned count; // Number of bytes written by last operation +}; + +fdobuf& endl(fdobuf& fd); + +extern fdobuf fout; +extern fdobuf ferr; + +#endif // FDBUF__FDOBUF__H__ diff --git a/lib/fdbuf/fdobuf_chownmod.cc b/lib/fdbuf/fdobuf_chownmod.cc new file mode 100644 index 0000000..61bc34a --- /dev/null +++ b/lib/fdbuf/fdobuf_chownmod.cc @@ -0,0 +1,34 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include <string.h> +#include "fdbuf.h" +#include <sys/stat.h> +#include <unistd.h> + +bool fdobuf::chown(uid_t uid, gid_t gid) const +{ + if(error()) + return false; + return fchown(fd, uid, gid) != -1; +} + +bool fdobuf::chmod(mode_t mode) const +{ + if(error()) + return false; + return fchmod(fd, mode) != -1; +} diff --git a/lib/fdbuf/fdobuf_seek.cc b/lib/fdbuf/fdobuf_seek.cc new file mode 100644 index 0000000..ab376ea --- /dev/null +++ b/lib/fdbuf/fdobuf_seek.cc @@ -0,0 +1,48 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "fdbuf.h" +#include <errno.h> +#include <unistd.h> + +bool fdobuf::seek(unsigned o) +{ + if(flags) + return false; + + lock(); + unsigned buf_start = offset; + unsigned buf_end = offset + buflength; + if(o >= buf_start && o < buf_end) { + bufpos = o - buf_start; + } + else { + if(!nflush(false)) { + unlock(); + return false; + } + if(lseek(fd, o, SEEK_SET) != (off_t)o) { + errnum = errno; + flags |= flag_error; + unlock(); + return false; + } + offset = o; + } + count = 0; + unlock(); + return true; +} diff --git a/lib/fdbuf/fdobuf_signed.cc b/lib/fdbuf/fdobuf_signed.cc new file mode 100644 index 0000000..4282ace --- /dev/null +++ b/lib/fdbuf/fdobuf_signed.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "fdbuf.h" +#include <limits.h> + +#define MAXSTRLEN ((sizeof(signed long)*CHAR_BIT)/3) + +fdobuf& fdobuf::operator<<(signed long i) +{ + if(i == 0) + return operator<<('0'); + if(i < 0) { + operator<<('-'); + i = -i; + } + char buf[MAXSTRLEN+1]; + char* ptr = buf+MAXSTRLEN; + *ptr-- = 0; + while(i) { + *ptr-- = i % 10 + '0'; + i /= 10; + } + return operator<<(ptr+1); +} diff --git a/lib/fdbuf/fdobuf_unsigned.cc b/lib/fdbuf/fdobuf_unsigned.cc new file mode 100644 index 0000000..61fc098 --- /dev/null +++ b/lib/fdbuf/fdobuf_unsigned.cc @@ -0,0 +1,34 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "fdbuf.h" +#include <limits.h> + +#define MAXSTRLEN ((sizeof(signed long)*CHAR_BIT)/3) + +fdobuf& fdobuf::operator<<(unsigned long i) +{ + if(i == 0) + return operator<<('0'); + char buf[MAXSTRLEN+1]; + char* ptr = buf+MAXSTRLEN; + *ptr-- = 0; + while(i) { + *ptr-- = i % 10 + '0'; + i /= 10; + } + return operator<<(ptr+1); +} diff --git a/lib/fdbuf/tlsibuf.cc b/lib/fdbuf/tlsibuf.cc new file mode 100644 index 0000000..787c323 --- /dev/null +++ b/lib/fdbuf/tlsibuf.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "tlsibuf.h" + +/////////////////////////////////////////////////////////////////////////////// +// Class tlsibuf +/////////////////////////////////////////////////////////////////////////////// +tlsibuf::tlsibuf(gnutls_session_t s, unsigned bufsz) + : fdibuf(-1, false, bufsz), session(s) +{ + flags &= ~flag_closed; +} + +ssize_t tlsibuf::_read(char* buf, ssize_t len) +{ + return gnutls_record_recv(session, buf, len); +} diff --git a/lib/fdbuf/tlsibuf.h b/lib/fdbuf/tlsibuf.h new file mode 100644 index 0000000..3c74365 --- /dev/null +++ b/lib/fdbuf/tlsibuf.h @@ -0,0 +1,32 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef FDBUF__TLSIBUF__H__ +#define FDBUF__TLSIBUF__H__ + +#include "fdibuf.h" +#include <gnutls/gnutls.h> + +class tlsibuf : public fdibuf +{ +public: + tlsibuf(gnutls_session_t, unsigned bufsz = FDBUF_SIZE); +protected: + gnutls_session_t session; + virtual ssize_t _read(char* buf, ssize_t len); +}; + +#endif // FDBUF__TLSIBUF__H__ diff --git a/lib/fdbuf/tlsobuf.cc b/lib/fdbuf/tlsobuf.cc new file mode 100644 index 0000000..83d68f8 --- /dev/null +++ b/lib/fdbuf/tlsobuf.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "tlsobuf.h" + +/////////////////////////////////////////////////////////////////////////////// +// Class tlsobuf +/////////////////////////////////////////////////////////////////////////////// +tlsobuf::tlsobuf(gnutls_session_t s, unsigned bufsz) + : fdobuf(-1, false, bufsz), session(s) +{ + flags &= ~flag_closed; +} + +ssize_t tlsobuf::_write(const char* buf, ssize_t len) +{ + return gnutls_record_send(session, buf, len); +} diff --git a/lib/fdbuf/tlsobuf.h b/lib/fdbuf/tlsobuf.h new file mode 100644 index 0000000..43f68ec --- /dev/null +++ b/lib/fdbuf/tlsobuf.h @@ -0,0 +1,32 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef FDBUF__TLSOBUF__H__ +#define FDBUF__TLSOBUF__H__ + +#include "fdobuf.h" +#include <gnutls/gnutls.h> + +class tlsobuf : public fdobuf +{ +public: + tlsobuf(gnutls_session_t, unsigned bufsz = FDBUF_SIZE); +protected: + gnutls_session_t session; + virtual ssize_t _write(const char* buf, ssize_t len); +}; + +#endif // FDBUF__TLSOBUF__H__ diff --git a/lib/forkexec.cc b/lib/forkexec.cc new file mode 100644 index 0000000..a59115d --- /dev/null +++ b/lib/forkexec.cc @@ -0,0 +1,168 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include <errno.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include "cli++/cli++.h" +#include "fdbuf/fdbuf.h" +#include "mystring/mystring.h" +#include "defines.h" +#include "errcodes.h" +#include "forkexec.h" + +#define ERR(MSG) do{ ferr << cli_program << ": " << MSG << ": " << strerror(errno) << endl; } while(0) +#define FAIL(MSG) do{ ERR(MSG); return false; }while(0) + +static int fdnull = -1; + +fork_exec::fork_exec(const char* p) + : pid(-1), name(p) +{ +} + +fork_exec::~fork_exec() +{ + wait(); +} + +bool fork_exec::operator!() const +{ + return pid < 0; +} + +bool fork_exec::start(const char* args[], int redirn, int redirs[]) +{ + autoclose_pipe pipes[redirn]; + for (int i = 0; i < redirn; i++) { + if (redirs[i] == REDIRECT_PIPE_TO || redirs[i] == REDIRECT_PIPE_FROM) + if (!pipes[i].open()) + FAIL("Could not create pipe"); + if (redirs[i] == REDIRECT_NULL) + if (fdnull < 0) + if ((fdnull = open("/dev/null", O_RDWR)) < 0) + FAIL("Could not open \"/dev/null\""); + } + if ((pid = fork()) < 0) + FAIL("Could not fork"); + if (pid == 0) { + // Child process, exec program + for (int i = 0; i < redirn; i++) { + int r = redirs[i]; + if (r == REDIRECT_NULL) + dup2(fdnull, i); + else if (r == REDIRECT_PIPE_FROM) { + dup2(pipes[i][1], i); + pipes[i].close(); + } + else if (r == REDIRECT_PIPE_TO) { + dup2(pipes[i][0], i); + pipes[i].close(); + } + else if (r > 0) { + dup2(r, i); + if (r >= redirn) + close(r); + } + } + execv(args[0], (char**)args); + ERR("Could not exec " << name); + _exit(ERR_EXEC_FAILED); + } + for (int i = 0; i < redirn; i++) { + if (redirs[i] == REDIRECT_PIPE_TO) + redirs[i] = pipes[i].extract(1); + else if (redirs[i] == REDIRECT_PIPE_FROM) + redirs[i] = pipes[i].extract(0); + } + return true; +} + +bool fork_exec::start(const char* program, int redirn, int redirs[]) +{ + const char* args[2] = { program, NULL }; + return start(args, redirn, redirs); +} + +int fork_exec::wait_status() +{ + if (pid > 0) { + int status; + if (waitpid(pid, &status, 0) == pid) { + pid = -1; + return status; + } + } + return -1; +} + +bool fork_exec::wait() +{ + if (pid > 0) { + int status = wait_status(); + if (status < 0) + FAIL("Error catching the return value from " << name); + if (WIFEXITED(status)) { + status = WEXITSTATUS(status); + if (status) { + ferr << cli_program << ": " << name << " failed: " << status << endl; + return false; + } + } + else + FAIL(name << " crashed or was killed"); + } + return true; +} + +mystring program_path(const char* program) +{ + return CONFIG_PATH(BIN, NULL, program); +} + +static const char* nqpath() +{ + static mystring cache; + if (!cache) { + const char* env; + if ((env = getenv("NULLMAILER_QUEUE")) != NULL) + cache = env; + else + cache = CONFIG_PATH(SBIN, NULL, "nullmailer-queue"); + } + return cache.c_str(); +} + +queue_pipe::queue_pipe() + : fork_exec("nullmailer-queue") +{ +} + +int queue_pipe::start() +{ + int redirs[] = { REDIRECT_PIPE_TO, REDIRECT_NULL, REDIRECT_NULL }; + if (!fork_exec::start(nqpath(), 3, redirs)) + return -1; + return redirs[0]; +} diff --git a/lib/forkexec.h b/lib/forkexec.h new file mode 100644 index 0000000..9fdd98b --- /dev/null +++ b/lib/forkexec.h @@ -0,0 +1,43 @@ +#ifndef NULLMAILER__FORK_EXEC__H +#define NULLMAILER__FORK_EXEC__H + +#include <sys/types.h> +#include <sys/wait.h> +#include <signal.h> +#include "mystring/mystring.h" +#include "autoclose.h" +#include "configio.h" + +mystring program_path(const char* program); + +#define REDIRECT_NONE -1 +#define REDIRECT_NULL -2 +#define REDIRECT_PIPE_FROM -3 +#define REDIRECT_PIPE_TO -4 + +class fork_exec +{ + private: + pid_t pid; + const char* name; + + public: + fork_exec(const char*); + ~fork_exec(); + bool operator!() const; + + bool start(const char* args[], int redirn, int redirs[]); + bool start(const char* program, int redirn, int redirs[]); + bool wait(); + int wait_status(); + inline void kill(int sig) { ::kill(pid, sig); } +}; + +class queue_pipe : public fork_exec +{ + public: + queue_pipe(); + int start(); +}; + +#endif diff --git a/lib/hostname.cc b/lib/hostname.cc new file mode 100644 index 0000000..76ac54e --- /dev/null +++ b/lib/hostname.cc @@ -0,0 +1,45 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include "mystring/mystring.h" +#include "configio.h" +#include "hostname.h" +#include "canonicalize.h" + +mystring me; +mystring defaulthost; +mystring defaultdomain; + +void read_hostnames() +{ + int nome; + nome = 0; + if (!config_read("me", me)) { + nome = 1; + me = "me"; + } + if (!config_read("defaultdomain", defaultdomain)) + defaultdomain = nome ? "defaultdomain" : me.c_str(); + if (!config_read("defaulthost", defaulthost)) + defaulthost = nome ? "defaulthost" : me.c_str(); + canonicalize(defaulthost); +} diff --git a/lib/hostname.h b/lib/hostname.h new file mode 100644 index 0000000..f1cfb0c --- /dev/null +++ b/lib/hostname.h @@ -0,0 +1,10 @@ +#ifndef NULLMAILER__HOSTNAME__H__ +#define NULLMAILER__HOSTNAME__H__ + +extern mystring me; +extern mystring defaulthost; +extern mystring defaultdomain; + +void read_hostnames(); + +#endif diff --git a/lib/itoa.cc b/lib/itoa.cc new file mode 100644 index 0000000..54c927d --- /dev/null +++ b/lib/itoa.cc @@ -0,0 +1,23 @@ +#include "itoa.h" + +const char *itoa(long v, int digits) +{ + static char buf[INTLENGTH]; + bool neg = false; + if(v < 0) { + v = -v; + neg = true; + } + char* ptr = buf + INTLENGTH; + *--ptr = '\0'; + do { + *--ptr = (v % 10) + '0'; + v /= 10; + --digits; + } while(v != 0); + while(digits > 0 && ptr > buf-1) + *--ptr = '0', --digits; + if(neg) + *--ptr = '-'; + return ptr; +} diff --git a/lib/itoa.h b/lib/itoa.h new file mode 100644 index 0000000..8458805 --- /dev/null +++ b/lib/itoa.h @@ -0,0 +1,11 @@ +#ifndef ITOA__H__ +#define ITOA__H__ + +#ifndef INTLENGTH +#define INTLENGTH 64 +/* 40 digits is long enough to handle unsigned 128-bit numbers */ +#endif + +const char *itoa(long, int = 0); + +#endif diff --git a/lib/list.h b/lib/list.h new file mode 100644 index 0000000..3bbd750 --- /dev/null +++ b/lib/list.h @@ -0,0 +1,197 @@ +#ifndef LIST__H__ +#define LIST__H__ + +template<class T> struct list_node +{ + list_node* next; + T data; + list_node(T d, list_node* n = 0) : next(n), data(d) { } + ~list_node() { } +}; + +template<class T> class list_iterator; +template<class T> class const_list_iterator; + +template<class T> class list +{ +public: + typedef list_node<T> node; + typedef list_iterator<T> iter; + typedef const_list_iterator<T> const_iter; + friend class list_iterator<T>; + friend class const_list_iterator<T>; + + list() + : head(0), tail(0), cnt(0) + { + } + list(const list&); + + ~list() + { + empty(); + } + + unsigned count() const + { + return cnt; + } + + void empty() + { + while(head) { + node* next = head->next; + delete head; + head = next; + } + tail = 0; + cnt = 0; + } + + bool append(T data) + { + node* n = new node(data); + if(tail) + tail->next = n; + else + head = n; + tail = n; + ++cnt; + return true; + } + bool prepend(T data) + { + head = new node(data, head); + if(!tail) + tail = head; + ++cnt; + return true; + } + bool remove(iter&); +private: + node* head; + node* tail; + unsigned cnt; +}; + +template<class T> class const_list_iterator +{ + friend class list<T>; +private: + inline void go_next() + { + prev = curr; + if(curr) + curr = curr->next; + } +public: + const_list_iterator(const list<T>& l) + : lst(l), prev(0), curr(l.head) + { + } + void operator++() + { + go_next(); + } + void operator++(int) + { + go_next(); + } + T operator*() const + { + return curr->data; + } + bool operator!() const + { + return curr == 0; + } + operator bool() const + { + return !operator!(); + } +private: + const list<T>& lst; + // g++ 3.2 insists + const typename list<T>::node* prev; + const typename list<T>::node* curr; +}; + +template<class T> +list<T>::list(const list<T>& that) + : head(0), tail(0), cnt(0) +{ + for(const_iter i = that; i; ++i) + append(*i); +} + +template<class T> class list_iterator +{ + friend class list<T>; +private: + inline void go_next() + { + prev = curr; + if(curr) + curr = curr->next; + } +public: + list_iterator(list<T>& l) + : lst(l), prev(0), curr(l.head) + { + } + void operator++() + { + go_next(); + } + void operator++(int) + { + go_next(); + } + T operator*() const + { + return curr->data; + } + T& operator*() + { + return curr->data; + } + bool operator!() const + { + return curr == 0; + } + operator bool() const + { + return !operator!(); + } +private: + list<T>& lst; + typename list<T>::node* prev; + typename list<T>::node* curr; +}; + +template<class T> +bool list<T>::remove(list<T>::iter& iter) +{ + if(this != &iter.lst) + return false; + if(!iter.curr) + return false; + if(iter.prev) { + iter.prev->next = iter.curr->next; + if(iter.curr == tail) + tail = iter.prev; + delete iter.curr; + iter.curr = iter.prev->next; + } + else { + head = iter.curr->next; + if(!head) + tail = 0; + delete iter.curr; + iter.curr = head; + } + --cnt; + return true; +} + +#endif // LIST__H__ diff --git a/lib/listtest.cc b/lib/listtest.cc new file mode 100644 index 0000000..fc10c71 --- /dev/null +++ b/lib/listtest.cc @@ -0,0 +1,50 @@ +#include <iostream.h> +#include "list.h" + +typedef list<int> ilist; +typedef ilist::iter iiter; + +void test_remove_first() +{ + ilist l; + l.append(1); + l.append(2); + iiter i(l); + l.remove(i); + if(!i) cout << "After removing first, iter no longer valid\n"; + else if(*i != 2) cout << "After removing first, iter is wrong\n"; + if(l.count() != 1) cout << "After removing first, count is wrong\n"; +} + +void test_remove_mid() +{ + ilist l; + l.append(1); + l.append(2); + l.append(3); + iiter i(l); + i++; + l.remove(i); + if(!i) cout << "After removing middle, iter no longer valid\n"; + else if(*i != 3) cout << "After removing middle, iter is wrong\n"; + if(l.count() != 2) cout << "After removing middle, count is wrong\n"; +} + +void test_remove_last() +{ + ilist l; + l.append(1); + l.append(2); + iiter i(l); + i++; + l.remove(i); + if(i) cout << "After removing last, iter is still valid\n"; + if(l.count() != 1) cout << "After removing last, count is wrong\n"; +} + +int main() { + test_remove_first(); + test_remove_mid(); + test_remove_last(); + return 0; +} diff --git a/lib/make_defines.sh b/lib/make_defines.sh new file mode 100644 index 0000000..405a37d --- /dev/null +++ b/lib/make_defines.sh @@ -0,0 +1,8 @@ +#!/bin/sh +( + echo "extern const char QUEUE_DIR[]=\"$1\";" + echo "extern const char CONFIG_DIR[]=\"$2\";" + echo "extern const char PROTOCOLS_DIR[]=\"$3\";" + echo "extern const char BIN_DIR[]=\"$4\";" + echo "extern const char SBIN_DIR[]=\"$5\";" +) > defines.cc diff --git a/lib/makefield.cc b/lib/makefield.cc new file mode 100644 index 0000000..2af0382 --- /dev/null +++ b/lib/makefield.cc @@ -0,0 +1,89 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include "defines.h" +#include <unistd.h> +#include "ac/time.h" +#include "itoa.h" +#include "mystring/mystring.h" + +mystring make_date(time_t t) +{ + char buf[256]; + if (t == 0) + t = time(0); + struct tm* l = localtime(&t); + strftime(buf, 256, "%a, %d %b %Y %H:%M:%S ", l); +#ifdef TM_HAS_GMTOFF + long tznum = l->TM_HAS_GMTOFF/60; +#else + long tznum = -timezone/60; +#ifdef TM_HAS_ISDST + int daylight = l->TM_HAS_ISDST; +#endif // TM_HAS_ISDST + if(daylight) + tznum += 60; +#endif // TM_HAS_GMTOFF + char tz[6]; + tz[0] = '+'; + if(tznum < 0) { + tznum = -tznum; + tz[0] = '-'; + } + long tzhours = tznum / 60; + tz[1] = (tzhours/10)%10 + '0'; + tz[2] = tzhours%10 + '0'; + long tzmins = tznum % 60; + tz[3] = (tzmins/10)%10 + '0'; + tz[4] = tzmins%10 + '0'; + tz[5] = 0; + return mystringjoin(buf) + tz; +} + +// Message ID strings have the form SECONDS.USEC.PID.nullmailer@HOST +mystring make_messageid(const mystring& idhost) +{ + struct timeval tv; + gettimeofday(&tv, 0); + mystring tmp = "<"; + tmp += itoa(tv.tv_sec); + tmp += '.'; + tmp += itoa(tv.tv_usec, 6); + tmp += '.'; + tmp += itoa(getpid()); + tmp += ".nullmailer@"; + tmp += idhost; + tmp += '>'; + return tmp; +} + +mystring make_boundary() +{ + struct timeval tv; + gettimeofday(&tv, 0); + mystring tmp = itoa(tv.tv_sec); + tmp += '.'; + tmp += itoa(tv.tv_usec, 6); + tmp += '.'; + tmp += itoa(getpid()); + return tmp; +} diff --git a/lib/makefield.h b/lib/makefield.h new file mode 100644 index 0000000..9686ef2 --- /dev/null +++ b/lib/makefield.h @@ -0,0 +1,8 @@ +#ifndef NULLMAILER__MAKEFIELD__H__ +#define NULLMAILER__MAKEFIELD__H__ + +extern mystring make_date(time_t t = 0); +extern mystring make_messageid(const mystring& idhost); +extern mystring make_boundary(); + +#endif // NULLMAILER__MAKEFIELD__H__ diff --git a/lib/mergelib.sh b/lib/mergelib.sh new file mode 100644 index 0000000..f9b7a94 --- /dev/null +++ b/lib/mergelib.sh @@ -0,0 +1,16 @@ +set -e +archive="$1" +shift +tmpdir=".libmerge.$archive.$$.$RANDOM.$USER" +mkdir "$tmpdir" +cd "$tmpdir" +trap 'cd ..; rm -rf "$tmpdir"' EXIT +for input in "$@"; do + dir="`basename "$input"`" + mkdir "$dir" + cd "$dir" + "${AR:-ar}" x ../../"$input" + cd .. +done +"${AR:-ar}" rc ../"$archive" */* +"${RANLIB:-ranlib}" ../"$archive" diff --git a/lib/mystring/ChangeLog b/lib/mystring/ChangeLog new file mode 100644 index 0000000..458067b --- /dev/null +++ b/lib/mystring/ChangeLog @@ -0,0 +1,116 @@ +2000-04-09 Bruce Guenter <bguenter@bguenter.pointsnorth.com> + + * count.cc (count): Added this routine to count the number of + instances of a single character in a string. + +2000-04-06 Bruce Guenter <bguenter@bguenter.pointsnorth.com> + + * fdobuf.cc (operator<<): Moved this routine out of an inline + declaration. + + * iter.h: Moved the mystring_iter declarations into this file. + + * rep.h: Moved the mystringrep declarations into this file. + + * join.h: Moved the mystringjoin declarations into this file. + + * mystring.h (class mystring): Renamed the "find_first" and + "find_last" routines that scan for items in a set to + "find_first_of" and "find_last_of". + +1999-08-15 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * mystring.h (class mystring_iter): Changed the default seperator + for strings to '\0' + (class mystring): Added a NUL constant (single 0 byte string). + +1999-07-26 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * mystring.h (class mystring_iter): Added this new iterator class, + taken from code used in vmailmgr. It is used to iterate over + essentially a token-delimited string. + +1999-07-14 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * Removed all vestiges of mystringtmp support from this library. + +1999-07-13 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * append.cc: Fixed same bug as below in append. + + * assign.cc: Fixed bug in assign and dup where NULL pointers + caused a crash. + + * append.cc, assign.cc: removed the mystringtmp versions of the + append, assign, and dup operations. mystringtmp now only exists + in the cons[2-7].cc files and tmp.cc + + * find.cc: Split this file into find_first, find_first_of, + find_last, and find_last_of. + +1999-07-12 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * join.cc (traverse): This routine traverses the linked list and + builds a mystringrep out of it. + + * mystring.h: Renamed TRACE to MYSTRING_TRACE. + Added a new mystringjoin class. This class is used to turn a list + of calls to "operator+" into a single constructor by building a + linked list on the stack. This will replace mystringtmp. + + * rep.cc (struct _rep_stats): Fixed the percentage function to not + do divide-by-zero; modified the "slack" reporting to report a + percentage of the requested length. + + * assign.cc: Re-added dup and assign functions for "char*" type, + moving the constructors and assignment operators inline. + + * append.cc: Re-added append functions for "char*" type. + +1999-07-08 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * mystring.h (class mystring): Eliminated the "mystring" return + value for the assign and append operators, since this return value + is never used and causes extra operations. + + * operator_plus.cc: Created this new file containing the + "operator+" routine. + + * operator_pleq.cc: Created this new file containing all the + "operator+=" routines. + + * assign.cc: Created this new file containing all the assign and + dup primitives. + + * mystring.h (class mystring): Removed the += operator taking + "mystringtmp" parameter, and replaced it with two routines, one + for "const mystring&", and one for "const char*". This results in + a net code shrinkage. + + * rep.cc (struct _rep_stats): Added this optional statistics + gathering class to determine the effectiveness of the slack space + and string appending. + + * append.cc (append): Use the new rep->append routine. + + * rep.cc (alloc): Allocate an amount of "slack" space when + allocating a string, to allow for later appends. + (append): This new routine appends a string to the current rep if + and only if the current rep has a single reference and the new + length of the string will fit within the current size. If not, it + makes a dup of this+str and returns a pointer to it. + +1999-06-07 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * tmp.cc: Removed the contents of checkstr, and moved the + necessary parts into the constructors. This makes the code more + efficient, as the constructors are adequately specific to omit + some of the branches in the comparisons. It also ensures that len + is always initialized, allowing many of the simple functions to be + moved inline to the header file. + +1999-04-01 Bruce Guenter <bguenter@mikhail.qcc.sk.ca> + + * cons7.cc (mystring): Wrote this constructor to build a string + from 7 inputs. + diff --git a/lib/mystring/Makefile.am b/lib/mystring/Makefile.am new file mode 100644 index 0000000..c9abf42 --- /dev/null +++ b/lib/mystring/Makefile.am @@ -0,0 +1,26 @@ +noinst_LIBRARIES = libmystring.a +EXTRA_DIST = ChangeLog iter.h join.h mystring.h rep.h trace.h + +AM_CPPFLAGS = -I$(top_srcdir)/lib + +libmystring_a_SOURCES = \ + append.cc \ + assign.cc \ + count.cc \ + fdobuf.cc \ + find_first_ch.cc \ + find_first_of.cc \ + find_last_ch.cc \ + find_last_of.cc \ + iter.cc \ + join.cc \ + lower.cc \ + lstrip.cc \ + mystring.cc \ + rep.cc \ + starts_with.cc \ + rstrip.cc \ + sub.cc \ + subst.cc \ + strip.cc \ + upper.cc diff --git a/lib/mystring/Makefile.in b/lib/mystring/Makefile.in new file mode 100644 index 0000000..7c49873 --- /dev/null +++ b/lib/mystring/Makefile.in @@ -0,0 +1,583 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = lib/mystring +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libmystring_a_AR = $(AR) $(ARFLAGS) +libmystring_a_LIBADD = +am_libmystring_a_OBJECTS = append.$(OBJEXT) assign.$(OBJEXT) \ + count.$(OBJEXT) fdobuf.$(OBJEXT) find_first_ch.$(OBJEXT) \ + find_first_of.$(OBJEXT) find_last_ch.$(OBJEXT) \ + find_last_of.$(OBJEXT) iter.$(OBJEXT) join.$(OBJEXT) \ + lower.$(OBJEXT) lstrip.$(OBJEXT) mystring.$(OBJEXT) \ + rep.$(OBJEXT) starts_with.$(OBJEXT) rstrip.$(OBJEXT) \ + sub.$(OBJEXT) subst.$(OBJEXT) strip.$(OBJEXT) upper.$(OBJEXT) +libmystring_a_OBJECTS = $(am_libmystring_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(libmystring_a_SOURCES) +DIST_SOURCES = $(libmystring_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ + ChangeLog +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HAVE_GETADDRINFO = @HAVE_GETADDRINFO@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RM = @RM@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libmystring.a +EXTRA_DIST = ChangeLog iter.h join.h mystring.h rep.h trace.h +AM_CPPFLAGS = -I$(top_srcdir)/lib +libmystring_a_SOURCES = \ + append.cc \ + assign.cc \ + count.cc \ + fdobuf.cc \ + find_first_ch.cc \ + find_first_of.cc \ + find_last_ch.cc \ + find_last_of.cc \ + iter.cc \ + join.cc \ + lower.cc \ + lstrip.cc \ + mystring.cc \ + rep.cc \ + starts_with.cc \ + rstrip.cc \ + sub.cc \ + subst.cc \ + strip.cc \ + upper.cc + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/mystring/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu lib/mystring/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libmystring.a: $(libmystring_a_OBJECTS) $(libmystring_a_DEPENDENCIES) $(EXTRA_libmystring_a_DEPENDENCIES) + $(AM_V_at)-rm -f libmystring.a + $(AM_V_AR)$(libmystring_a_AR) libmystring.a $(libmystring_a_OBJECTS) $(libmystring_a_LIBADD) + $(AM_V_at)$(RANLIB) libmystring.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/append.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assign.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/count.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdobuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find_first_ch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find_first_of.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find_last_ch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find_last_of.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/join.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lower.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstrip.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mystring.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rep.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rstrip.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/starts_with.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strip.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subst.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upper.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/mystring/append.cc b/lib/mystring/append.cc new file mode 100644 index 0000000..d0120a5 --- /dev/null +++ b/lib/mystring/append.cc @@ -0,0 +1,19 @@ +#include <string.h> +#include "mystring.h" +#include "trace.h" + +void mystring::append(const char* str, size_t len) +{ + if(!str || !len) + return; + if(!*this) + assign(str, len); + else + rep = rep->append(str, len); +} + +void mystring::append(const char* in) +{ + if(in) + append(in, strlen(in)); +} diff --git a/lib/mystring/assign.cc b/lib/mystring/assign.cc new file mode 100644 index 0000000..5a7b6a7 --- /dev/null +++ b/lib/mystring/assign.cc @@ -0,0 +1,55 @@ +#include "mystring.h" +#include "trace.h" +#include <ctype.h> +#include <string.h> + +void mystring::dupnil() +{ + trace(""); + rep = &nil; + rep->attach(); +} + +void mystring::assign(const char* in) +{ + if(in) + assign(in, strlen(in)); + else { + mystringrep* tmp = rep; + dupnil(); + tmp->detach(); + } +} + +void mystring::assign(const char* in, size_t len) +{ + trace("in='" << in << "'"); + if(in != rep->buf) { + mystringrep* tmp = rep; + dup(in, len); + tmp->detach(); + } +} + +void mystring::dup(const char* in, size_t len) +{ + trace("in='" << in << "'"); + rep = mystringrep::dup(in, len); + rep->attach(); +} + +void mystring::dup(const char* in) +{ + if(in) + dup(in, strlen(in)); + else + dupnil(); +} + +void mystring::operator=(const mystringjoin& in) +{ + mystringrep* tmp = rep; + rep = in.traverse(); + rep->attach(); + tmp->detach(); +} diff --git a/lib/mystring/count.cc b/lib/mystring/count.cc new file mode 100644 index 0000000..36b0a04 --- /dev/null +++ b/lib/mystring/count.cc @@ -0,0 +1,25 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "mystring.h" + +unsigned mystring::count(char ch) const +{ + unsigned c = 0; + for(int pos = find_first(ch); pos > 0; pos = find_first(ch, pos+1)) + ++c; + return c; +} diff --git a/lib/mystring/fdobuf.cc b/lib/mystring/fdobuf.cc new file mode 100644 index 0000000..ff967e6 --- /dev/null +++ b/lib/mystring/fdobuf.cc @@ -0,0 +1,9 @@ +#include "mystring.h" +#include "fdbuf/fdbuf.h" + +fdobuf& operator<<(fdobuf& out, const mystring& str) +{ + out.write(str.c_str(), str.length()); + return out; +} + diff --git a/lib/mystring/find_first_ch.cc b/lib/mystring/find_first_ch.cc new file mode 100644 index 0000000..0a652d0 --- /dev/null +++ b/lib/mystring/find_first_ch.cc @@ -0,0 +1,11 @@ +#include "mystring.h" +#include <string.h> + +int mystring::find_first(char ch, size_t offset) const +{ + if(offset >= rep->length) + return -1; + char* ptr = strchr(rep->buf+offset, ch); + return ptr ? ptr-rep->buf : -1; +} + diff --git a/lib/mystring/find_first_of.cc b/lib/mystring/find_first_of.cc new file mode 100644 index 0000000..f23e7f4 --- /dev/null +++ b/lib/mystring/find_first_of.cc @@ -0,0 +1,22 @@ +#include "mystring.h" +#include <string.h> + +int mystring::find_first_of(const char* setstr, size_t setlen, + size_t offset) const +{ + for(; offset < rep->length; offset++) { + if(memchr(setstr, rep->buf[offset], setlen)) + return offset; + } + return -1; +} + +int mystring::find_first_of(const char* setstr, size_t offset) const +{ + return find_first_of(setstr, strlen(setstr), offset); +} + +int mystring::find_first_of(const mystring& setstr, size_t offset) const +{ + return find_first_of(setstr.rep->buf, setstr.rep->length, offset); +} diff --git a/lib/mystring/find_last_ch.cc b/lib/mystring/find_last_ch.cc new file mode 100644 index 0000000..20d620a --- /dev/null +++ b/lib/mystring/find_last_ch.cc @@ -0,0 +1,14 @@ +#include "mystring.h" + +int mystring::find_last(char ch, size_t offset) const +{ + if(offset == (size_t)-1) + offset = rep->length-1; + const char* ptr = rep->buf + offset; + while(ptr >= rep->buf) { + if(*ptr == ch) + return ptr - rep->buf; + --ptr; + } + return -1; +} diff --git a/lib/mystring/find_last_of.cc b/lib/mystring/find_last_of.cc new file mode 100644 index 0000000..b8f8831 --- /dev/null +++ b/lib/mystring/find_last_of.cc @@ -0,0 +1,24 @@ +#include "mystring.h" +#include <string.h> + +int mystring::find_last_of(const char* setstr, size_t setlen, + size_t offset) const +{ + if(offset == (size_t)-1) + offset = rep->length-1; + for(int i = offset; i >= 0; --i) { + if(memchr(setstr, rep->buf[i], setlen)) + return i; + } + return -1; +} + +int mystring::find_last_of(const char* setstr, size_t offset) const +{ + return find_last_of(setstr, strlen(setstr), offset); +} + +int mystring::find_last_of(const mystring& setstr, size_t offset) const +{ + return find_last_of(setstr.rep->buf, setstr.rep->length, offset); +} diff --git a/lib/mystring/iter.cc b/lib/mystring/iter.cc new file mode 100644 index 0000000..3a84d1c --- /dev/null +++ b/lib/mystring/iter.cc @@ -0,0 +1,48 @@ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "mystring.h" + +mystring_iter::mystring_iter(const mystring& s, char e) + : str(s), sep(e), pos(0) +{ + advance(); +} + +mystring_iter::~mystring_iter() +{ +} + +void mystring_iter::advance() +{ + if(pos == -1) + return; + int i = str.find_first(sep, pos); + if(i == -1) { + if(pos >= 0 && pos < (int)str.length()) { + part = str.right(pos); + pos = str.length(); + } + else { + part = ""; + pos = -1; + } + } + else { + part = str.sub(pos, i-pos); + pos = i + 1; + } +} diff --git a/lib/mystring/iter.h b/lib/mystring/iter.h new file mode 100644 index 0000000..308c854 --- /dev/null +++ b/lib/mystring/iter.h @@ -0,0 +1,39 @@ +/* $Id: iter.h 616 2005-08-19 20:11:01Z bruce $ */ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef MYSTRING__ITER__H__ +#define MYSTRING__ITER__H__ + +class mystring_iter +{ + const mystring str; + const char sep; + int pos; + mystring part; + + void advance(); +public: + mystring_iter(const mystring&, char = '\0'); + ~mystring_iter(); + + operator bool() const { return pos >= 0; } + bool operator!() const { return pos < 0; } + mystring operator*() const { return part; } + void operator++() { advance(); } +}; + +#endif diff --git a/lib/mystring/join.cc b/lib/mystring/join.cc new file mode 100644 index 0000000..435765f --- /dev/null +++ b/lib/mystring/join.cc @@ -0,0 +1,61 @@ +#include "mystring.h" +#include <string.h> + +// This "join" class relies on one fairly obscure detail in the C++ +// standard: temporaries are destructed only after the entire +// "full-expression" has completed. That is, if the sequence: +// f(f(f(x))) creates three temporary objects, the inner objects are +// destroyed only after the execution has completed. This allows us +// to build a complete linked-list on the stack. Tricky, but efficient! + +struct tmpitem +{ + const char* str; + unsigned len; +}; + +mystringrep* mystringjoin::traverse() const +{ + // At first glance, a recursive implementation would be the most logical + // way of doing this, but it turned out to be a significant loss. This + // method traverses the pointer chain to first determine the length, and + // then to do the actual copying. + + // Note the use of do/while loops to avoid a test at the head of the loop + // which will always succeed (there is always at least one node or item). + unsigned count = 0; + const mystringjoin* node = this; + do { + ++count; + } while((node = node->prev) != 0); + + // The use of a temporary array avoids re-traversing the pointer + // chain, which is a slight performance win. + tmpitem items[count]; + + unsigned length = 0; + node = this; + tmpitem* item = items; + do { + unsigned l = node->rep ? node->rep->length : strlen(node->str); + length += l; + item->str = node->str; + item->len = l; + ++item; + } while((node = node->prev) != 0); + + // Since the chain is constructed such that the last item is the + // first node, the string gets constructed in reverse order. + mystringrep* rep = mystringrep::alloc(length); + char* buf = rep->buf + length; + item = items; + do { + unsigned l = item->len; + buf -= l; + memcpy(buf, item->str, l); + ++item; + } while(--count != 0); + + rep->buf[length] = 0; + return rep; +} diff --git a/lib/mystring/join.h b/lib/mystring/join.h new file mode 100644 index 0000000..0c73176 --- /dev/null +++ b/lib/mystring/join.h @@ -0,0 +1,76 @@ +/* $Id: join.h 616 2005-08-19 20:11:01Z bruce $ */ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef MYSTRING__JOIN__H__ +#define MYSTRING__JOIN__H__ + +class mystringjoin +{ +private: + const mystringjoin* prev; + mystringrep* rep; + const char* str; + + mystringjoin(); +public: + mystringjoin(const mystringjoin& j) + : prev(j.prev), rep(j.rep), str(j.str) + { + rep->attach(); + } + mystringjoin(const mystring& s) + : prev(0), rep(s.rep), str(s.rep->buf) + { + rep->attach(); + } + mystringjoin(const char* s) + : prev(0), rep(0), str(s) + { + } + mystringjoin(const mystringjoin& p, const mystring& s) + : prev(&p), rep(s.rep), str(s.rep->buf) + { + rep->attach(); + } + mystringjoin(const mystringjoin& p, const char* s) + : prev(&p), rep(0), str(s) + { + } + ~mystringjoin() + { + if(rep) rep->detach(); + } + mystringrep* traverse() const; +}; + +inline mystring::mystring(const mystringjoin& j) + : rep(j.traverse()) +{ + rep->attach(); +} + +inline mystringjoin operator+(const mystringjoin& a, const mystring& b) +{ + return mystringjoin(a, b); +} + +inline mystringjoin operator+(const mystringjoin& a, const char* b) +{ + return mystringjoin(a, b); +} + +#endif diff --git a/lib/mystring/lower.cc b/lib/mystring/lower.cc new file mode 100644 index 0000000..b51b51d --- /dev/null +++ b/lib/mystring/lower.cc @@ -0,0 +1,19 @@ +#include "mystring.h" +#include <ctype.h> + +mystring mystring::lower() const +{ + const unsigned length = rep->length; + char buf[length+1]; + const char* in = rep->buf + length; + bool changed = false; + for(char* out = buf+length; out >= buf; in--, out--) + if(isupper(*in)) + *out = tolower(*in), changed = true; + else + *out = *in; + if(!changed) + return *this; + else + return mystring(buf, length); +} diff --git a/lib/mystring/lstrip.cc b/lib/mystring/lstrip.cc new file mode 100644 index 0000000..66ee2d0 --- /dev/null +++ b/lib/mystring/lstrip.cc @@ -0,0 +1,10 @@ +#include "mystring.h" +#include <ctype.h> + +mystring mystring::lstrip() const +{ + const char* ptr = rep->buf; + while(*ptr && isspace(*ptr)) + ++ptr; + return ptr; +} diff --git a/lib/mystring/mystring.cc b/lib/mystring/mystring.cc new file mode 100644 index 0000000..c04bf2f --- /dev/null +++ b/lib/mystring/mystring.cc @@ -0,0 +1,28 @@ +#include "mystring.h" +#include "trace.h" +#include <ctype.h> +#include <string.h> + +#ifdef MYSTRING_TRACE +mystring::~mystring() +{ + trace("rep=" << (void*)rep); + rep->detach(); +} +#endif + +int mystring::operator!=(const char* in) const +{ + if(rep->buf == in) + return 0; + return strcmp(rep->buf, in); +} + +int mystring::operator!=(const mystring& in) const +{ + if(rep->buf == in.rep->buf) + return 0; + return strcmp(rep->buf, in.rep->buf); +} + +const mystring mystring::NUL("", 1); diff --git a/lib/mystring/mystring.h b/lib/mystring/mystring.h new file mode 100644 index 0000000..1752772 --- /dev/null +++ b/lib/mystring/mystring.h @@ -0,0 +1,131 @@ +/* $Id: mystring.h 635 2005-11-02 17:37:50Z bruce $ */ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef MYSTRING__H__ +#define MYSTRING__H__ + +#include <sys/types.h> +#include "mystring/rep.h" + +class mystringjoin; +class mystring +{ + friend class mystringtmp; + friend class mystringjoin; +private: + mystringrep* rep; + +protected: + void dupnil(); + void dup(const char*, size_t); + void dup(const char*); + void assign(const char*); + void assign(const char*, size_t); +public: + static const mystring NUL; + + mystring() { dupnil(); } + mystring(const char* s) { dup(s); } + mystring(const mystring& s) { dup(s.rep->buf, s.rep->length); } + mystring(const char* str, size_t len) { dup(str, len); } + mystring(const mystringjoin&); + ~mystring(); + + const char* c_str() const { return rep->buf; } + + bool operator!() const { return empty(); } + + char operator[](size_t i) const { return rep->buf[i]; } + + size_t length() const { return rep->length; } + + bool empty() const { return rep->length == 0; } + + int operator!=(const char* in) const; + int operator!=(const mystring& in) const; + bool operator==(const char* in) const + { + return !operator!=(in); + } + bool operator==(const mystring& in) const + { + return !operator!=(in); + } + + void operator=(const char* in) { assign(in); } + void operator=(const mystring& in) { assign(in.rep->buf, in.rep->length); } + void operator=(const mystringjoin& in); + + mystring subst(char from, char to) const; + + mystring lower() const; + mystring upper() const; + + bool starts_with(const mystring&) const; + bool starts_with(const char*) const; + bool starts_with(const char*, size_t) const; + + int find_first(char, size_t = 0) const; + int find_first_of(const mystring&, size_t = 0) const; + int find_first_of(const char*, size_t = 0) const; + int find_first_of(const char*, size_t, size_t) const; + + int find_last(char, size_t = (size_t)-1) const; + int find_last_of(const mystring&, size_t = (size_t)-1) const; + int find_last_of(const char*, size_t = 0) const; + int find_last_of(const char*, size_t, size_t) const; + + mystring left(size_t) const; + mystring right(size_t) const; + mystring sub(size_t, size_t) const; + + mystring lstrip() const; + mystring rstrip() const; + mystring strip() const; + + unsigned count(char ch) const; + + void append(const char*); + void append(const char*, size_t); + + void operator+=(const mystring& str) {append(str.rep->buf, str.rep->length);} + void operator+=(const char* str) { append(str); } + void operator+=(char ch) + { + char str[2] = { ch, 0 }; + append(str, 1); + } +}; + +#ifndef MYSTRING_TRACE +inline mystring::~mystring() +{ + rep->detach(); +} +#endif + +#include "mystring/iter.h" +#include "mystring/join.h" + +class fdobuf; +fdobuf& operator<<(fdobuf& out, const mystring& str); + +//istream& operator>>(istream& in, mystring& str); + +typedef mystring string; + +#endif diff --git a/lib/mystring/rep.cc b/lib/mystring/rep.cc new file mode 100644 index 0000000..bc939d7 --- /dev/null +++ b/lib/mystring/rep.cc @@ -0,0 +1,157 @@ +#include "mystring.h" +#include "trace.h" +#include <ctype.h> +#include <string.h> + +mystringrep nil = { 0, 1, 1, "" }; + +static const unsigned replength = sizeof(unsigned)*3; + +static const unsigned sizestep = sizeof(unsigned); +static const unsigned slackdiv = 4; +static const unsigned slackmax = 16; + +#ifdef MYSTRINGREP_STATS + +#include "fdbuf.h" + +struct _rep_stats +{ + unsigned allocs; + unsigned alloc_size; + unsigned alloc_len; + + unsigned appends; + unsigned appends_dup; + + _rep_stats() + : allocs(0) + { + } + + void stat(const char* name, unsigned value) + { + ferr << "mystringrep: " << name << ": " << value << '\n'; + } + void pcnt(const char* name, unsigned denom, unsigned divis) + { + ferr << "mystringrep: " << name << ": " + << denom << '/' << divis << '='; + if(divis) ferr << denom * 100 / divis << '%'; + else ferr << "N/A"; + ferr << '\n'; + } + + ~_rep_stats() + { + stat(" size step", sizestep); + stat(" slack divisor", slackdiv); + stat(" slack maximum", slackmax); + stat(" allocs", allocs); + stat(" alloc length", alloc_len); + stat(" alloc size", alloc_size); + pcnt(" alloc slack", alloc_size-alloc_len, alloc_len); + stat("alloc overhead", allocs*replength); + pcnt(" appends->dup", appends_dup, appends); + } +}; + +static _rep_stats stats; + +#define ACCOUNT(NAME,VALUE) stats. NAME += VALUE + +#else // MYSTRINGREP_STATS + +#define ACCOUNT(NAME,VALUE) + +#endif // MYSTRINGREP_STATS + +/////////////////////////////////////////////////////////////////////////////// +// class mystringrep +/////////////////////////////////////////////////////////////////////////////// +mystringrep* mystringrep::alloc(unsigned length) +{ + ACCOUNT(allocs, 1); + trace_static("length=" << length); + if(length == 0) + return &nil; + + ACCOUNT(alloc_len, length); + unsigned slack = length / slackdiv; + if(slack > slackmax) + slack = slackmax; + unsigned size = length+1 + sizestep-1 + slack; + size = size - size % sizestep; + ACCOUNT(alloc_size, size); + + mystringrep* ptr = (mystringrep*)new char[size+replength]; + ptr->length = length; + ptr->references = 0; + ptr->size = size; + return ptr; +} + +mystringrep* mystringrep::dup(const char* str, unsigned length) +{ + trace_static("str=" << (void*)str << " length=" << length); + if(length == 0) + return &nil; + mystringrep* ptr = alloc(length); + memcpy(ptr->buf, str, length); + ptr->buf[length] = 0; + return ptr; +} + +mystringrep* mystringrep::dup(const char* str1, unsigned length1, + const char* str2, unsigned length2) +{ + trace_static(""); + if(length1+length2 == 0) + return &nil; + mystringrep* ptr = alloc(length1+length2); + memcpy(ptr->buf, str1, length1); + memcpy(ptr->buf+length1, str2, length2); + ptr->buf[length1+length2] = 0; + return ptr; +} + +mystringrep* mystringrep::append(const char* str, unsigned len) +{ + ACCOUNT(appends, 1); + unsigned newlen = length + len; + // If there are more than one references, always make a duplicate + // Also, if this does not have enough space to add the new string, dup it + if(references > 1 || newlen >= size) { + ACCOUNT(appends_dup, 1); + mystringrep* tmp = dup(buf, length, str, len); + tmp->attach(); + detach(); + return tmp; + } + // Otherwise, just add the new string to the end of this + else { + memcpy(buf+length, str, len); + buf[newlen] = 0; + length = newlen; + return this; + } +} + +#ifdef MYSTRING_TRACE +void mystringrep::attach() +{ + trace("references=" << references); + ++references; +} +#endif + +void mystringrep::detach() +{ + trace("references=" << references); + + --references; + if(!references) { + trace("deleting this"); + delete this; + } +} diff --git a/lib/mystring/rep.h b/lib/mystring/rep.h new file mode 100644 index 0000000..4ca0bff --- /dev/null +++ b/lib/mystring/rep.h @@ -0,0 +1,47 @@ +/* $Id: rep.h 616 2005-08-19 20:11:01Z bruce $ */ +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef MYSTRING__REP__H__ +#define MYSTRING__REP__H__ + +struct mystringrep +{ + unsigned length; + unsigned references; + unsigned size; + char buf[1]; + + void attach(); + void detach(); + mystringrep* append(const char*, unsigned); + + static mystringrep* alloc(unsigned); + static mystringrep* dup(const char*, unsigned); + static mystringrep* dup(const char*, unsigned, + const char*, unsigned); +}; + +#ifndef MYSTRING_TRACE +inline void mystringrep::attach() +{ + references++; +} +#endif + +extern mystringrep nil; + +#endif diff --git a/lib/mystring/rstrip.cc b/lib/mystring/rstrip.cc new file mode 100644 index 0000000..b66f8ce --- /dev/null +++ b/lib/mystring/rstrip.cc @@ -0,0 +1,10 @@ +#include "mystring.h" +#include <ctype.h> + +mystring mystring::rstrip() const +{ + const char* ptr = rep->buf + rep->length - 1; + while(ptr >= rep->buf && isspace(*ptr)) + --ptr; + return mystring(rep->buf, ptr-rep->buf+1); +} diff --git a/lib/mystring/starts_with.cc b/lib/mystring/starts_with.cc new file mode 100644 index 0000000..180fcbe --- /dev/null +++ b/lib/mystring/starts_with.cc @@ -0,0 +1,17 @@ +#include "mystring.h" +#include <string.h> + +bool mystring::starts_with(const char* that, size_t len) const +{ + return len <= rep->length && memcmp(that, rep->buf, len) == 0; +} + +bool mystring::starts_with(const char* that) const +{ + return starts_with(that, strlen(that)); +} + +bool mystring::starts_with(const mystring& that) const +{ + return starts_with(that.rep->buf, that.rep->length); +} diff --git a/lib/mystring/strip.cc b/lib/mystring/strip.cc new file mode 100644 index 0000000..7ee251f --- /dev/null +++ b/lib/mystring/strip.cc @@ -0,0 +1,13 @@ +#include "mystring.h" +#include <ctype.h> + +mystring mystring::strip() const +{ + const char* start = rep->buf; + while(*start && isspace(*start)) + ++start; + const char* end = rep->buf + rep->length - 1; + while(end >= start && isspace(*end)) + --end; + return mystring(start, end-start+1); +} diff --git a/lib/mystring/sub.cc b/lib/mystring/sub.cc new file mode 100644 index 0000000..c0918db --- /dev/null +++ b/lib/mystring/sub.cc @@ -0,0 +1,37 @@ +#include "mystring.h" + +// return the sub-string ending at 'offset' +mystring mystring::left(size_t offset) const +{ + if(offset > rep->length) + return *this; + else + return mystring(rep->buf, offset); +} + +// return the sub-string starting at 'offset' +mystring mystring::right(size_t offset) const +{ + if(offset >= rep->length) + return mystring(); + else if(offset == 0) + return *this; + else + return mystring(rep->buf+offset, rep->length-offset); +} + +// return the 'len' characters of the string starting at 'offset' +mystring mystring::sub(size_t offset, size_t len) const +{ + // return right(offset).left(len); + if(len == 0) + return mystring(); + else if(offset == 0 && len >= rep->length) + return *this; + else { + if(len+offset >= rep->length) + len = rep->length - offset; + return mystring(rep->buf+offset, len); + } +} + diff --git a/lib/mystring/subst.cc b/lib/mystring/subst.cc new file mode 100644 index 0000000..f5172cc --- /dev/null +++ b/lib/mystring/subst.cc @@ -0,0 +1,18 @@ +#include "mystring.h" + +mystring mystring::subst(char from, char to) const +{ + const unsigned length = rep->length; + char buf[length+1]; + const char* in = rep->buf + length; + bool changed = true; + for(char* out = buf+length; out >= buf; in--, out--) + if(*in == from) + *out = to, changed = true; + else + *out = *in; + if(!changed) + return *this; + else + return mystring(buf, length); +} diff --git a/lib/mystring/trace.h b/lib/mystring/trace.h new file mode 100644 index 0000000..d6942a7 --- /dev/null +++ b/lib/mystring/trace.h @@ -0,0 +1,11 @@ +/* $Id: trace.h 616 2005-08-19 20:11:01Z bruce $ */ +#include "mystring.h" + +#ifdef MYSTRING_TRACE +ostream& operator<<(ostream& out, const mystringtmp& s); +#define trace(X) cerr << (void*)this << "->" << __PRETTY_FUNCTION__ << X << endl +#define trace_static(X) cerr << __PRETTY_FUNCTION__ << X << endl +#else +#define trace(X) do { } while(0) +#define trace_static(X) do { } while(0) +#endif diff --git a/lib/mystring/upper.cc b/lib/mystring/upper.cc new file mode 100644 index 0000000..5015770 --- /dev/null +++ b/lib/mystring/upper.cc @@ -0,0 +1,21 @@ +#include "mystring.h" +#include <ctype.h> + +mystring mystring::upper() const +{ + const unsigned length = rep->length; + char buf[length+1]; + const char* in = rep->buf + length; + bool changed = false; + for(char* out = buf+length; out >= buf; in--, out--) + if(islower(*in)) { + *out = toupper(*in); + changed = true; + } + else + *out = *in; + if(!changed) + return *this; + else + return mystring(buf, length); +} diff --git a/lib/netstring.cc b/lib/netstring.cc new file mode 100644 index 0000000..784d941 --- /dev/null +++ b/lib/netstring.cc @@ -0,0 +1,13 @@ +#include "config.h" +#include "netstring.h" +#include "itoa.h" + +mystring str2net(const mystring& s) +{ + return mystringjoin(itoa(s.length())) + ":" + s + ","; +} + +mystring strnl2net(const mystring& s) +{ + return mystringjoin(itoa(s.length()+1)) + ":" + s + "\012,"; +} diff --git a/lib/netstring.h b/lib/netstring.h new file mode 100644 index 0000000..d5a1a19 --- /dev/null +++ b/lib/netstring.h @@ -0,0 +1,8 @@ +#ifndef NULLMAILER__NETSTRING__H__ +#define NULLMAILER__NETSTRING__H__ + +#include "mystring/mystring.h" +mystring str2net(const mystring&); +mystring strnl2net(const mystring&); + +#endif // NULLMAILER__NETSTRING__H__ diff --git a/lib/selfpipe.cc b/lib/selfpipe.cc new file mode 100644 index 0000000..83b390c --- /dev/null +++ b/lib/selfpipe.cc @@ -0,0 +1,104 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include <sys/types.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> +#include "selfpipe.h" + +static int fds[2] = { -1, -1 }; + +static int fcntl_fl_on(int fd, int flag) +{ + int flags; + int newflags; + if ((flags = fcntl(fd, F_GETFL, 0)) == -1) + return 0; + if ((newflags = flags | flag) != flags) + if (fcntl(fd, F_SETFL, newflags)) + return 0; + return 1; +} + +selfpipe::selfpipe() +{ + if (fds[0] < 0) { + if (pipe(fds) != -1) { + if (fcntl_fl_on(fds[0], O_NONBLOCK) + && fcntl_fl_on(fds[1], O_NONBLOCK) + && fcntl_fl_on(fds[1], FD_CLOEXEC) + && fcntl_fl_on(fds[1], FD_CLOEXEC)) + return; + + close(fds[0]); + close(fds[1]); + } + fds[0] = fds[1] = -1; + } +} + +selfpipe::operator bool() const +{ + return fds[0] >= 0; +} + +static void catcher(int sig) +{ + signal(sig, catcher); + write(fds[1], &sig, sizeof sig); +} + +void selfpipe::catchsig(int sig) +{ + signal(sig, catcher); +} + +int selfpipe::caught() +{ + int buf; + if (read(fds[0], &buf, sizeof buf) == sizeof buf) + return buf; + return 0; +} + +int selfpipe::waitsig(int timeout) +{ + if (timeout > 0) { + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(fds[0], &fdset); + struct timeval tv; + tv.tv_sec = timeout; + tv.tv_usec = 0; + int s; + while ((s = select(fds[0] + 1, &fdset, 0, 0, + (timeout <= 0) ? 0 : &tv)) == -1) { + if (errno != EINTR) + return -1; + } + if (s != 1) + return 0; + } + return caught(); +} diff --git a/lib/selfpipe.h b/lib/selfpipe.h new file mode 100644 index 0000000..1ad2136 --- /dev/null +++ b/lib/selfpipe.h @@ -0,0 +1,16 @@ +#ifndef NULLMAILER_SELFPIPE__H__ +#define NULLMAILER_SELFPIPE__H__ + +class selfpipe +{ + public: + selfpipe(); + + operator bool() const; + + void catchsig(int sig); + int caught(); + int waitsig(int timeout = 0); +}; + +#endif // NULLMAILER_SELFPIPE__H__ diff --git a/lib/setenv.cc b/lib/setenv.cc new file mode 100644 index 0000000..6fcfeb0 --- /dev/null +++ b/lib/setenv.cc @@ -0,0 +1,41 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include <config.h> +#include <stdlib.h> +#include <string.h> +#include "setenv.h" + +#ifndef HAVE_SETENV +// This is not really a full emulation of setenv, but close enough +int setenv(const char* var, const char* val, int overwrite) +{ + size_t varlen = strlen(var); + size_t vallen = strlen(val); + char* str = (char*)malloc(varlen+vallen+2); + if (str == 0) return -1; + memcpy(str, var, varlen); + str[varlen] = '='; + memcpy(str+varlen+1, val, vallen); + str[varlen+vallen+1] = 0; + return putenv(str); +} +#endif diff --git a/lib/setenv.h b/lib/setenv.h new file mode 100644 index 0000000..771ee27 --- /dev/null +++ b/lib/setenv.h @@ -0,0 +1,6 @@ +#ifndef NULLMAILER__SETENV__H__ +#define NULLMAILER__SETENV__H__ + +extern "C" int setenv(const char*, const char*, int); + +#endif diff --git a/lib/tcpconnect.cc b/lib/tcpconnect.cc new file mode 100644 index 0000000..d4cf9a9 --- /dev/null +++ b/lib/tcpconnect.cc @@ -0,0 +1,175 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include <errno.h> +#include <netdb.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <unistd.h> +#include "errcodes.h" +#include "itoa.h" +#include "connect.h" + +static int err_return(int errn, int dflt) +{ + if (errn == HOST_NOT_FOUND) + return -ERR_HOST_NOT_FOUND; + if (errn == NO_ADDRESS) + return -ERR_NO_ADDRESS; + if (errn == NO_RECOVERY || errn == EAI_FAIL) + return -ERR_GHBN_FATAL; + if (errn == TRY_AGAIN || errn == EAI_AGAIN) + return -ERR_GHBN_TEMP; + if (errn == EAI_NONAME) + return -ERR_HOST_NOT_FOUND; + if (errn == ECONNREFUSED) + return -ERR_CONN_REFUSED; + if (errn == ETIMEDOUT) + return -ERR_CONN_TIMEDOUT; + if (errn == ENETUNREACH) + return -ERR_CONN_UNREACHABLE; + return -dflt; +} + +#ifdef HAVE_GETADDRINFO + +static int getaddr(const char* hostname, int port, struct addrinfo** result) +{ + const char *service = itoa(port, 6); + struct addrinfo req; + memset(&req, 0, sizeof(req)); + req.ai_flags = AI_NUMERICSERV; + req.ai_socktype = SOCK_STREAM; + int e = getaddrinfo(hostname, service, &req, result); + return e ? err_return(e, ERR_GHBN_TEMP) : 0; +} + +static bool canbind(int family, const struct addrinfo* ai) +{ + for (; ai; ai = ai->ai_next) + if (ai->ai_family == family) + return true; + return false; +} + +static bool bindit(int fd, int family, const struct addrinfo* ai) +{ + for (; ai; ai = ai->ai_next) + if (ai->ai_family == family) + if (bind(fd, ai->ai_addr, ai->ai_addrlen) == 0) + return true; + return false; +} + +int tcpconnect(const char* hostname, int port, const char* source) +{ + struct addrinfo* res; + int err = getaddr(hostname, port, &res); + if (err) + return err; + struct addrinfo* source_addr = NULL; + if (source) { + err = getaddr(source, 0, &source_addr); + if (err) + return err; + } + int s = -1; + err = ERR_CONN_FAILED; + struct addrinfo* orig_res = res; + + if (source_addr) + // Check if some address is the same family as the source + for (; res != NULL; res = res->ai_next) + if (canbind(res->ai_family, source_addr)) + break; + if (res == NULL) + return -ERR_BIND_FAILED; + + for (; res != NULL; res = res->ai_next) { + if (!source_addr || canbind(res->ai_family, source_addr)) { + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if(s > 0) { + if(source_addr && !bindit(s, res->ai_family, source_addr)) { + close(s); + err = ERR_BIND_FAILED; + s = -1; + break; + } + if(connect(s, res->ai_addr, res->ai_addrlen) == 0) + break; + close(s); + s = -1; + } + } + } + + freeaddrinfo(orig_res); + if (source_addr) + freeaddrinfo(source_addr); + + if(s < 0) + return err_return(errno, err); + return s; +} + +#else + +static int sethostbyname(const char* hostname, struct sockaddr_in& sa) +{ + struct hostent *he = gethostbyname(hostname); + if(!he) + return err_return(h_errno, ERR_GHBN_TEMP); + memcpy(&sa.sin_addr, he->h_addr, he->h_length); + return 0; +} + +int tcpconnect(const char* hostname, int port, const char* source) +{ + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + int e = sethostbyname(hostname, sa); + if(e) return e; + struct sockaddr_in source_sa; + memset(&source_sa, 0, sizeof source_sa); + if(source) { + e = sethostbyname(source, source_sa); + if(e) return e; + } + sa.sin_family = AF_INET; + sa.sin_port = htons(port); + int s = socket(PF_INET, SOCK_STREAM, 0); + if(s == -1) + return -ERR_SOCKET; + if(source && bind(s, (sockaddr*)&source_sa, sizeof source_sa) != 0) { + close(s); + return err_return(errno, ERR_BIND_FAILED); + } + if(connect(s, (sockaddr*)&sa, sizeof(sa)) != 0) { + close(s); + return err_return(errno, ERR_CONN_FAILED); + } + return s; +} + +#endif @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2013-10-28.13; # UTC + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/nullmailer-2.1.spec b/nullmailer-2.1.spec new file mode 100644 index 0000000..65e170f --- /dev/null +++ b/nullmailer-2.1.spec @@ -0,0 +1,95 @@ +Name: nullmailer +Summary: Simple relay-only mail transport agent +Version: 2.1 +Release: 1 +License: GPL +Group: Networking/Daemons +Source: http://untroubled.org/nullmailer/archive/%{version}/nullmailer-%{version}.tar.gz +BuildRoot: /tmp/nullmailer-root +URL: http://untroubled.org/nullmailer/ +Packager: Bruce Guenter <bruce@untroubled.org> +Provides: smtpdaemon +Conflicts: sendmail +Conflicts: qmail +Requires: supervise-scripts >= 3.2 +Requires: gnutls +BuildRequires: gnutls-devel +Requires(pre,preun): shadow-utils + +%description +Nullmailer is a mail transport agent designed to only relay all its +messages through a fixed set of "upstream" hosts. It is also designed +to be secure. + +%prep +%setup + +%build +CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" \ +./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-tls + +make + +%install +rm -fr $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/etc +mkdir -p $RPM_BUILD_ROOT/usr/lib +mkdir -p $RPM_BUILD_ROOT/var/service/nullmailer/log +mkdir -p $RPM_BUILD_ROOT/var/log/nullmailer + +make DESTDIR=$RPM_BUILD_ROOT install-strip +ln -s ../sbin/sendmail $RPM_BUILD_ROOT/usr/lib/sendmail +install scripts/nullmailer.run $RPM_BUILD_ROOT/var/service/nullmailer/run +install scripts/nullmailer-log.run $RPM_BUILD_ROOT/var/service/nullmailer/log/run + +%clean +rm -rf $RPM_BUILD_ROOT + +%pre +PATH="/sbin:/usr/sbin:$PATH" export PATH +if [ "$1" = 1 ]; then + # pre-install instructions + grep ^nullmail: /etc/group >/dev/null || groupadd -r nullmail + grep ^nullmail: /etc/passwd >/dev/null || useradd -d /var/lock/svc/nullmailer -g nullmail -M -r -s /bin/true nullmail +fi + +%post +if ! [ -L /service/nullmailer ]; then + svc-add /var/service/nullmailer +fi +if ! [ -s /etc/nullmailer/me ]; then + /bin/hostname --fqdn >/etc/nullmailer/me +fi +if ! [ -s /etc/nullmailer/defaultdomain ]; then + /bin/hostname --domain >/etc/nullmailer/defaultdomain +fi + +%preun +if [ "$1" = 0 ]; then + svc-remove nullmailer +fi + +%postun +if [ "$1" = 0 ]; then + # post-erase instructions + /usr/sbin/userdel nullmail + /usr/sbin/groupdel nullmail +fi + +%files +%defattr(-,nullmail,nullmail) +%doc AUTHORS BUGS ChangeLog COPYING INSTALL NEWS README TODO doc/DIAGRAM +%dir /etc/nullmailer +%attr(04711,nullmail,nullmail) /usr/bin/mailq +/usr/bin/nullmailer-inject +/usr/bin/nullmailer-smtpd +/usr/lib/sendmail +%dir /usr/libexec/nullmailer +/usr/libexec/nullmailer/* +%{_mandir}/*/* +%attr(04711,nullmail,nullmail) /usr/sbin/nullmailer-queue +/usr/sbin/nullmailer-send +/usr/sbin/sendmail +%dir /var/log/nullmailer +/var/service/nullmailer +/var/spool/nullmailer diff --git a/protocols/Makefile.am b/protocols/Makefile.am new file mode 100644 index 0000000..ae10a58 --- /dev/null +++ b/protocols/Makefile.am @@ -0,0 +1,18 @@ +libexecdir = @libexecdir@/nullmailer + +libexec_PROGRAMS = smtp qmqp +AM_CPPFLAGS = -I$(top_srcdir)/lib + +if TLS +TLS_SOURCES = tls_gnutls.cc +TLS_LDADD = -lgnutls +else +TLS_SOURCES = tls_none.cc +TLS_LDADD = +endif + +smtp_SOURCES = smtp.cc protocol.cc $(TLS_SOURCES) protocol.h +smtp_LDADD = ../lib/cli++/libcli++.a ../lib/libnullmailer.a $(TLS_LDADD) + +qmqp_SOURCES = qmqp.cc protocol.cc $(TLS_SOURCES) protocol.h +qmqp_LDADD = ../lib/cli++/libcli++.a ../lib/libnullmailer.a $(TLS_LDADD) diff --git a/protocols/Makefile.in b/protocols/Makefile.in new file mode 100644 index 0000000..6437822 --- /dev/null +++ b/protocols/Makefile.in @@ -0,0 +1,610 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +libexec_PROGRAMS = smtp$(EXEEXT) qmqp$(EXEEXT) +subdir = protocols +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(libexecdir)" +PROGRAMS = $(libexec_PROGRAMS) +am__qmqp_SOURCES_DIST = qmqp.cc protocol.cc tls_none.cc tls_gnutls.cc \ + protocol.h +@TLS_FALSE@am__objects_1 = tls_none.$(OBJEXT) +@TLS_TRUE@am__objects_1 = tls_gnutls.$(OBJEXT) +am_qmqp_OBJECTS = qmqp.$(OBJEXT) protocol.$(OBJEXT) $(am__objects_1) +qmqp_OBJECTS = $(am_qmqp_OBJECTS) +am__DEPENDENCIES_1 = +qmqp_DEPENDENCIES = ../lib/cli++/libcli++.a ../lib/libnullmailer.a \ + $(am__DEPENDENCIES_1) +am__smtp_SOURCES_DIST = smtp.cc protocol.cc tls_none.cc tls_gnutls.cc \ + protocol.h +am_smtp_OBJECTS = smtp.$(OBJEXT) protocol.$(OBJEXT) $(am__objects_1) +smtp_OBJECTS = $(am_smtp_OBJECTS) +smtp_DEPENDENCIES = ../lib/cli++/libcli++.a ../lib/libnullmailer.a \ + $(am__DEPENDENCIES_1) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(qmqp_SOURCES) $(smtp_SOURCES) +DIST_SOURCES = $(am__qmqp_SOURCES_DIST) $(am__smtp_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HAVE_GETADDRINFO = @HAVE_GETADDRINFO@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RM = @RM@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@/nullmailer +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir)/lib +@TLS_FALSE@TLS_SOURCES = tls_none.cc +@TLS_TRUE@TLS_SOURCES = tls_gnutls.cc +@TLS_FALSE@TLS_LDADD = +@TLS_TRUE@TLS_LDADD = -lgnutls +smtp_SOURCES = smtp.cc protocol.cc $(TLS_SOURCES) protocol.h +smtp_LDADD = ../lib/cli++/libcli++.a ../lib/libnullmailer.a $(TLS_LDADD) +qmqp_SOURCES = qmqp.cc protocol.cc $(TLS_SOURCES) protocol.h +qmqp_LDADD = ../lib/cli++/libcli++.a ../lib/libnullmailer.a $(TLS_LDADD) +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu protocols/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu protocols/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files + +clean-libexecPROGRAMS: + -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS) + +qmqp$(EXEEXT): $(qmqp_OBJECTS) $(qmqp_DEPENDENCIES) $(EXTRA_qmqp_DEPENDENCIES) + @rm -f qmqp$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(qmqp_OBJECTS) $(qmqp_LDADD) $(LIBS) + +smtp$(EXEEXT): $(smtp_OBJECTS) $(smtp_DEPENDENCIES) $(EXTRA_smtp_DEPENDENCIES) + @rm -f smtp$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(smtp_OBJECTS) $(smtp_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qmqp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smtp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_gnutls.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_none.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(libexecdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libexecPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libexecPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libexecPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libexecPROGRAMS cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libexecPROGRAMS \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-libexecPROGRAMS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/protocols/protocol.cc b/protocols/protocol.cc new file mode 100644 index 0000000..4545dd8 --- /dev/null +++ b/protocols/protocol.cc @@ -0,0 +1,155 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include "connect.h" +#include "errcodes.h" +#include "list.h" +#include "mystring/mystring.h" +#include "protocol.h" +#include "cli++/cli++.h" + +const char* user = 0; +const char* pass = 0; +int port = 0; +int auth_method = AUTH_DETECT; +int use_tls = 0; +int use_starttls = 0; +const char* remote = 0; +const char* source = 0; +const char* cli_help_suffix = ""; +const char* cli_args_usage = "< options 3< mail-file"; +const int cli_args_min = 0; +const int cli_args_max = 0; +cli_option cli_options[] = { + { 0, "host", cli_option::string, 0, &remote, + "Set the hostname for the remote", 0 }, + { 'p', "port", cli_option::integer, 0, &port, + "Set the port number on the remote host to connect to", 0 }, + { 0, "user", cli_option::string, 0, &user, + "Set the user name for authentication", 0 }, + { 0, "pass", cli_option::string, 0, &pass, + "Set the password for authentication", 0 }, + { 0, "auth-login", cli_option::flag, AUTH_LOGIN, &auth_method, + "Use AUTH LOGIN instead of auto-detecting in SMTP", 0 }, + { 0, "source", cli_option::string, 0, &source, + "Source address for connections", 0 }, +#ifdef HAVE_TLS + { 0, "tls", cli_option::flag, 1, &use_tls, + "Connect using TLS (on an alternate port by default)", 0 }, + { 0, "ssl", cli_option::flag, 1, &use_tls, + "Alias for --tls", 0 }, + { 0, "starttls", cli_option::flag, 1, &use_starttls, + "Use STARTTLS command", 0 }, + { 0, "x509certfile", cli_option::string, 0, &tls_x509certfile, + "Client certificate file", 0 }, + { 0, "x509keyfile", cli_option::string, 0, &tls_x509keyfile, + "Client certificate private key file", "the same file as --x509certfile" }, + { 0, "x509cafile", cli_option::string, 0, &tls_x509cafile, + "Certificate authority trust file", DEFAULT_CA_FILE }, + { 0, "x509crlfile", cli_option::string, 0, &tls_x509crlfile, + "Certificate revocation list file", 0 }, + { 0, "x509fmtder", cli_option::flag, true, &tls_x509derfmt, + "X.509 files are in DER format", "PEM format" }, + { 0, "insecure", cli_option::flag, true, &tls_insecure, + "Don't abort if server certificate fails validation", 0 }, + { 0, "tls-anon-auth", cli_option::flag, true, &tls_anon_auth, + "Use TLS anonymous authentication - needs --insecure option", 0 }, +#endif + {0, 0, cli_option::flag, 0, 0, 0, 0} +}; + +void protocol_fail(int e, const char* msg) +{ + fout << msg << endl; + ferr << cli_program << ": Failed: " << msg << endl; + exit(e); +} + +void protocol_succ(const char* msg) +{ + fout << msg << endl; + ferr << cli_program << ": Succeeded: " << msg << endl; + exit(0); +} + +static void plain_send(fdibuf& in, int fd) +{ + fdibuf netin(fd); + fdobuf netout(fd); + if (!netin || !netout) + protocol_fail(ERR_MSG_TEMPFAIL, "Error allocating I/O buffers"); + if (use_starttls) { + protocol_starttls(netin, netout); + tls_send(in, fd); + } + else + protocol_send(in, netin, netout); +} + +static void parse_option(mystring line) +{ + if (line[0] != '-') + line = "--" + line; + const char* arg = strdup(line.c_str()); + if (arg == NULL) + exit(ERR_CONFIG); + const char* args[3] = { argv0, arg, NULL }; + if (cli_parse_args(2, (char**)args) != 2) + exit(ERR_CONFIG); +} + +static void parse_options(void) +{ + mystring line; + while (fin.getline(line, '\n')) { + if (line.length() == 0) + return; + parse_option(line); + } + if (!fin.eof()) + exit(ERR_CONFIG); +} + +int cli_main(int, char*[]) +{ + parse_options(); + if (remote == 0) + protocol_fail(ERR_USAGE, "Remote host not set"); + if (port == 0) + port = use_tls ? default_tls_port : default_port; + if (port < 0) + protocol_fail(ERR_USAGE, "Invalid value for port"); + if (use_tls || use_starttls) + tls_init(remote); + fdibuf in(3, true); + protocol_prep(in); + int fd = tcpconnect(remote, port, source); + if(fd < 0) + protocol_fail(-fd, "Connect failed"); + if (use_tls) + tls_send(in, fd); + else + plain_send(in, fd); + return 0; +} diff --git a/protocols/protocol.h b/protocols/protocol.h new file mode 100644 index 0000000..2b1c9f6 --- /dev/null +++ b/protocols/protocol.h @@ -0,0 +1,37 @@ +#ifndef NULLMAILER__PROTOCOL__H__ +#define NULLMAILER__PROTOCOL__H__ + +#include "fdbuf/fdbuf.h" + +#define DEFAULT_CA_FILE "/etc/ssl/certs/ca-certificates.crt" + +extern const int default_port; +extern const int default_tls_port; +extern void protocol_fail(int e, const char* msg); +extern void protocol_succ(const char* msg); + +#define AUTH_DETECT 0 +#define AUTH_LOGIN 1 +#define AUTH_PLAIN 2 +extern const char* user; +extern const char* pass; +extern int auth_method; +extern int port; +extern int use_tls; +extern int use_starttls; + +extern void protocol_prep(fdibuf& in); +extern void protocol_send(fdibuf& in, fdibuf& netin, fdobuf& netout); +extern void protocol_starttls(fdibuf& netin, fdobuf& netout); + +extern int tls_insecure; +extern int tls_anon_auth; +extern const char* tls_x509certfile; +extern const char* tls_x509keyfile; +extern const char* tls_x509cafile; +extern const char* tls_x509crlfile; +extern int tls_x509derfmt; +extern void tls_init(const char* remote); +extern void tls_send(fdibuf& in, int fd); + +#endif diff --git a/protocols/qmqp.cc b/protocols/qmqp.cc new file mode 100644 index 0000000..830a9f5 --- /dev/null +++ b/protocols/qmqp.cc @@ -0,0 +1,141 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include <stdlib.h> +#include <unistd.h> +#include "errcodes.h" +#include "fdbuf/fdbuf.h" +#include "hostname.h" +#include "itoa.h" +#include "mystring/mystring.h" +#include "netstring.h" +#include "protocol.h" + +const int default_port = 628; +const int default_tls_port = -1; // No standard for QMQP over SSL exists +const char* cli_program = "qmqp"; +const char* cli_help_prefix = "Send an email message via QMQP\n"; + +class qmqp +{ + fdibuf& in; + fdobuf& out; +public: + qmqp(fdibuf& netin, fdobuf& netout); + ~qmqp(); + void send(fdibuf& msg, unsigned long size, const mystring& env); +}; + +qmqp::qmqp(fdibuf& netin, fdobuf& netout) + : in(netin), out(netout) +{ +} + +qmqp::~qmqp() +{ +} + +bool skip_envelope(fdibuf& msg) +{ + if(!msg.rewind()) + return false; + mystring tmp; + while(msg.getline(tmp)) + if(!tmp) + break; + return msg; +} + +void qmqp::send(fdibuf& msg, unsigned long size, const mystring& env) +{ + if(!skip_envelope(msg)) + protocol_fail(ERR_MSG_READ, "Error re-reading message"); + unsigned long fullsize = strlen(itoa(size)) + 1 + size + 1 + env.length(); + out << itoa(fullsize) << ":"; // Start the "outer" netstring + out << itoa(size) << ":"; // Start the message netstring + fdbuf_copy(msg, out, true); // Send out the message + out << "," // End the message netstring + << env // The envelope is already encoded + << ","; // End the "outer" netstring + if(!out.flush()) + protocol_fail(ERR_MSG_WRITE, "Error sending message to remote"); + mystring response; + if(!in.getnetstring(response)) + protocol_fail(ERR_PROTO, "Response from remote was not a netstring"); + switch(response[0]) { + case 'K': protocol_succ(response.c_str()+1); break; + case 'Z': protocol_fail(ERR_MSG_TEMPFAIL, response.c_str()+1); break; + case 'D': protocol_fail(ERR_MSG_PERMFAIL, response.c_str()+1); break; + default: protocol_fail(ERR_PROTO, "Invalid status byte in response"); + } +} + +bool compute_size(fdibuf& msg, unsigned long& size) +{ + char buf[4096]; + size = 0; + while(msg.read(buf, 4096)) + size += msg.last_count(); + if(msg.eof()) + size += msg.last_count(); + return size > 0; +} + +bool make_envelope(fdibuf& msg, mystring& env) +{ + mystring tmp; + while(msg.getline(tmp)) { + if(!tmp) + return true; + env += str2net(tmp); + } + return false; +} + +bool preload_data(fdibuf& msg, unsigned long& size, mystring& env) +{ + return make_envelope(msg, env) && + compute_size(msg, size); +} + +static unsigned long msg_size; +static mystring msg_envelope; + +void protocol_prep(fdibuf& in) +{ + if(!preload_data(in, msg_size, msg_envelope)) + protocol_fail(ERR_MSG_READ, "Error reading message"); +} + +void protocol_starttls(fdibuf& netin, fdobuf& netout) +{ + protocol_fail(ERR_USAGE, "QMQP does not support STARTTLS"); + (void)netin; + (void)netout; +} + +void protocol_send(fdibuf& in, fdibuf& netin, fdobuf& netout) +{ + alarm(60*60); // Connection must close after an hour + qmqp conn(netin, netout); + conn.send(in, msg_size, msg_envelope); +} diff --git a/protocols/smtp.cc b/protocols/smtp.cc new file mode 100644 index 0000000..706f757 --- /dev/null +++ b/protocols/smtp.cc @@ -0,0 +1,254 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include <stdlib.h> +#include <unistd.h> +#include "base64.h" +#include "connect.h" +#include "errcodes.h" +#include "fdbuf/fdbuf.h" +#include "itoa.h" +#include "mystring/mystring.h" +#include "protocol.h" + +const int default_port = 25; +const int default_tls_port = 465; +const char* cli_program = "smtp"; +const char* cli_help_prefix = "Send an email message via SMTP\n"; + +class smtp +{ + fdibuf& in; + fdobuf& out; + mystring caps; +public: + smtp(fdibuf& netin, fdobuf& netout); + ~smtp(); + int get(mystring& str); + int put(mystring cmd, mystring& result); + void docmd(mystring cmd, int range, mystring& result); + void docmd(mystring cmd, int range); + void dohelo(bool ehlo); + bool hascap(const char* name, const char* word = NULL); + void auth_login(void); + void auth_plain(void); + void send_data(fdibuf& msg); + void send_envelope(fdibuf& msg); + void send(fdibuf& msg); +}; + +smtp::smtp(fdibuf& netin, fdobuf& netout) + : in(netin), out(netout) +{ +} + +smtp::~smtp() +{ +} + +int smtp::get(mystring& str) +{ + mystring tmp; + str = ""; + int code = -1; + while(in.getline(tmp)) { + if(tmp[tmp.length()-1] == '\r') + tmp = tmp.left(tmp.length()-1); + code = atoi(tmp.c_str()); + if(!!str) + str += "\n"; + str += tmp; + if(tmp[3] != '-') + break; + } + return code; +} + +int smtp::put(mystring cmd, mystring& result) +{ + out << cmd << "\r\n"; + if(!out.flush()) + return -1; + return get(result); +} + +void smtp::docmd(mystring cmd, int range, mystring& result) +{ + int code; + if(!cmd) + code = get(result); + else + code = put(cmd, result); + if(code < range || code >= (range+100)) { + int e; + if(code >= 500) + e = ERR_MSG_PERMFAIL; + else if(code >= 400) + e = ERR_MSG_TEMPFAIL; + else + e = ERR_PROTO; + out << "QUIT\r\n"; + out.flush(); + protocol_fail(e, result.c_str()); + } +} + +void smtp::docmd(mystring cmd, int range) +{ + mystring msg; + docmd(cmd, range, msg); +} + +void smtp::dohelo(bool ehlo) +{ + mystring hh = getenv("HELOHOST"); + if (!hh) protocol_fail(1, "$HELOHOST is not set"); + docmd((ehlo ? "EHLO " : "HELO ") + hh, 200, caps); +} + +static int issep(char ch) +{ + return ch == ' ' || ch == '\n' || ch == '\0'; +} + +bool smtp::hascap(const char* name, const char* word) +{ + const size_t namelen = strlen(name); + int i = -1; + do { + const char* s = caps.c_str() + i + 5; + if (strncasecmp(s, name, namelen) == 0) { + if (s[namelen] == '\n') + return word == NULL; + else if (s[namelen] == ' ') { + if (word == NULL) + return true; + s += namelen + 1; + const size_t wordlen = strlen(word); + do { + if (strncasecmp(s, word, wordlen) == 0 && issep(s[wordlen])) + return true; + while (!issep(*s)) + ++s; + } while (*s++ == ' '); + return false; + } + } + i = caps.find_first('\n', i+1); + } while (i > 0); + return false; +} + +void smtp::auth_login(void) +{ + mystring encoded; + base64_encode(user, encoded); + docmd("AUTH LOGIN " + encoded, 300); + encoded = ""; + base64_encode(pass, encoded); + docmd(encoded, 200); +} + +void smtp::auth_plain(void) +{ + mystring plain(user); + plain += '\0'; + plain += user; + plain += '\0'; + plain += pass; + mystring encoded = "AUTH PLAIN "; + base64_encode(plain, encoded); + docmd(encoded, 200); +} + +void smtp::send_envelope(fdibuf& msg) +{ + mystring tmp; + msg.getline(tmp); + docmd("MAIL FROM:<" + tmp + ">", 200); + while(msg.getline(tmp) && !!tmp) + docmd("RCPT TO:<" + tmp + ">", 200); +} + +void smtp::send_data(fdibuf& msg) +{ + docmd("DATA", 300); + mystring tmp; + while(msg.getline(tmp)) { + if((tmp[0] == '.' && !(out << ".")) || + !(out << tmp << "\r\n")) + protocol_fail(ERR_MSG_WRITE, "Error sending message to remote"); + } + docmd(".", 200, tmp); + out << "QUIT\r\n"; + out.flush(); + protocol_succ(tmp.c_str()); +} + +void smtp::send(fdibuf& msg) +{ + send_envelope(msg); + send_data(msg); +} + +void protocol_prep(fdibuf&) +{ +} + +static int did_starttls = 0; + +void protocol_starttls(fdibuf& netin, fdobuf& netout) +{ + smtp conn(netin, netout); + conn.docmd("", 200); + conn.dohelo(true); + conn.docmd("STARTTLS", 200); + did_starttls = 1; +} + +void protocol_send(fdibuf& in, fdibuf& netin, fdobuf& netout) +{ + smtp conn(netin, netout); + if (!did_starttls) + conn.docmd("", 200); + + if (user != 0 && pass != 0) { + conn.dohelo(true); + if (auth_method == AUTH_LOGIN) + conn.auth_login(); + else if (auth_method == AUTH_PLAIN) + conn.auth_plain(); + else { + // Detect method + if (conn.hascap("AUTH", "PLAIN")) + conn.auth_plain(); + else if (conn.hascap("AUTH", "LOGIN")) + conn.auth_login(); + else + protocol_fail(ERR_MSG_TEMPFAIL, "Server does not advertise any supported authentication methods"); + } + } + else + conn.dohelo(false); + + conn.send(in); +} diff --git a/protocols/tls_gnutls.cc b/protocols/tls_gnutls.cc new file mode 100644 index 0000000..9e82968 --- /dev/null +++ b/protocols/tls_gnutls.cc @@ -0,0 +1,181 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include <config.h> +#include <unistd.h> +#include "errcodes.h" +#include "mystring/mystring.h" +#include "protocol.h" +#include <gnutls/gnutls.h> +#include <gnutls/x509.h> +#include "fdbuf/tlsibuf.h" +#include "fdbuf/tlsobuf.h" + +int tls_insecure = false; +int tls_anon_auth = false; +const char* tls_x509certfile = NULL; +const char* tls_x509keyfile = NULL; +const char* tls_x509cafile = NULL; +const char* tls_x509crlfile = NULL; +int tls_x509derfmt = false; + +static int gnutls_wrap(int ret, const char* msg) +{ + if (ret < 0) { + mystring m = msg; + m += ": "; + m += gnutls_strerror(ret); + protocol_fail(ERR_MSG_TEMPFAIL, m.c_str()); + } + return ret; +} + +static int cert_verify(gnutls_session_t session) +{ + if (tls_x509cafile != NULL && !tls_insecure) { + // Verify the certificate + unsigned int status = 0; + gnutls_wrap(gnutls_certificate_verify_peers2(session, &status), + "Could not verify SSL/TLS certificate"); + if (status != 0) + protocol_fail(ERR_MSG_TEMPFAIL, "Server SSL/TLS certificate is untrusted"); + + // Verify the hostname + unsigned int cert_list_size = 0; + const gnutls_datum_t* cert_list = gnutls_certificate_get_peers(session, &cert_list_size); + const char* hostname = (const char*)gnutls_session_get_ptr(session); + gnutls_x509_crt_t crt; + gnutls_wrap(gnutls_x509_crt_init(&crt), + "Error allocating memory"); + gnutls_wrap(gnutls_x509_crt_import(crt, &cert_list[0], GNUTLS_X509_FMT_DER), + "Error decoding SSL/TLS certificate"); + if (gnutls_x509_crt_check_hostname(crt, hostname) == 0) + protocol_fail(ERR_MSG_TEMPFAIL, "Server SSL/TLS certificate does not match hostname"); + gnutls_x509_crt_deinit(crt); + } + // All verification errors cause protocol to exit + return 0; +} + +static gnutls_session_t tls_session; + +void tls_cert_auth_init(const char* remote) +{ + gnutls_certificate_credentials_t creds; + gnutls_wrap(gnutls_global_init(), + "Error initializing TLS library"); + gnutls_wrap(gnutls_certificate_allocate_credentials(&creds), + "Error allocating TLS certificate"); + gnutls_wrap(gnutls_init(&tls_session, GNUTLS_CLIENT), + "Error creating TLS session"); +#ifdef HAVE_GNUTLS_PRIORITY_SET_DIRECT + gnutls_wrap(gnutls_priority_set_direct(tls_session, "NORMAL", NULL), + "Error setting TLS options"); +#else + gnutls_wrap(gnutls_set_default_priority(tls_session), + "Error setting TLS options"); +#endif + gnutls_wrap(gnutls_credentials_set(tls_session, GNUTLS_CRD_CERTIFICATE, creds), + "Error setting TLS credentials"); + gnutls_wrap(gnutls_server_name_set(tls_session, GNUTLS_NAME_DNS, remote, strlen(remote)), + "Error setting TLS server name"); + gnutls_session_set_ptr(tls_session, (void*)remote); +#ifdef HAVE_GNUTLS_SET_VERIFY_FUNCTION + gnutls_certificate_set_verify_function(creds, cert_verify); +#endif + gnutls_certificate_set_verify_flags(creds, 0); + + gnutls_x509_crt_fmt_t x509fmt = tls_x509derfmt ? GNUTLS_X509_FMT_DER : GNUTLS_X509_FMT_PEM; + if (tls_x509keyfile == NULL) + tls_x509keyfile = tls_x509certfile; + if (tls_x509certfile != NULL) + gnutls_wrap(gnutls_certificate_set_x509_key_file(creds, tls_x509certfile, tls_x509keyfile, x509fmt), + "Error setting SSL/TLS X.509 client certificate"); + if (tls_x509cafile == NULL && access(DEFAULT_CA_FILE, R_OK) == 0) + tls_x509cafile = DEFAULT_CA_FILE; + if (tls_x509cafile != NULL) + gnutls_wrap(gnutls_certificate_set_x509_trust_file(creds, tls_x509cafile, x509fmt), + "Error loading SSL/TLS X.509 trust file"); + if (tls_x509crlfile != NULL) + gnutls_wrap(gnutls_certificate_set_x509_crl_file(creds, tls_x509crlfile, x509fmt), + "Error loading SSL/TLS X.509 CRL file"); +} + +void tls_anon_auth_init(const char* remote) +{ + gnutls_anon_client_credentials_t anon_creds; + + gnutls_wrap(gnutls_global_init(), + "Error initializing TLS library"); + gnutls_wrap(gnutls_anon_allocate_client_credentials(&anon_creds), + "Error allocating TLS anonymous client credentials"); + gnutls_wrap(gnutls_init(&tls_session, GNUTLS_CLIENT), + "Error creating TLS session"); + +#ifdef HAVE_GNUTLS_PRIORITY_SET_DIRECT + gnutls_wrap(gnutls_priority_set_direct(tls_session, "NORMAL:+ANON-ECDH:+ANON-DH", NULL), + "Error setting TLS options"); +#else + gnutls_wrap(gnutls_set_default_priority(tls_session), + "Error setting TLS options"); +#endif + gnutls_wrap(gnutls_credentials_set(tls_session, GNUTLS_CRD_ANON, anon_creds), + "Error setting TLS credentials"); + gnutls_wrap(gnutls_server_name_set(tls_session, GNUTLS_NAME_DNS, remote, strlen(remote)), + "Error setting TLS server name"); + gnutls_session_set_ptr(tls_session, (void*)remote); +} + +void tls_init(const char* remote) +{ + if ((tls_x509certfile || tls_x509keyfile || tls_x509cafile || tls_x509crlfile) && (tls_anon_auth)) { + protocol_fail(ERR_MSG_TEMPFAIL, "Error: TLS certificate and TLS anonymous auth options cannot both be specified"); + } + + if (tls_anon_auth && tls_insecure) { + tls_anon_auth_init(remote); + } else { + tls_cert_auth_init(remote); + } +} + +void tls_send(fdibuf& in, int fd) +{ + int r; + + gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr_t)(long)fd); + + do { + r = gnutls_handshake(tls_session); + if (gnutls_error_is_fatal(r)) + gnutls_wrap(r, "Error completing TLS handshake"); + } while (r < 0); +#ifndef HAVE_GNUTLS_SET_VERIFY_FUNCTION + cert_verify(tls_session); +#endif + + tlsibuf tlsin(tls_session); + tlsobuf tlsout(tls_session); + if (!tlsin || !tlsout) + protocol_fail(ERR_MSG_TEMPFAIL, "Error allocating I/O buffers"); + + protocol_send(in, tlsin, tlsout); +} diff --git a/protocols/tls_none.cc b/protocols/tls_none.cc new file mode 100644 index 0000000..3f77d69 --- /dev/null +++ b/protocols/tls_none.cc @@ -0,0 +1,36 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "errcodes.h" +#include "protocol.h" + +void tls_init(const char* remote) +{ + protocol_fail(ERR_USAGE, "SSL/TLS not supported in this build"); + (void)remote; +} + +void tls_send(fdibuf& in, int fd) +{ + protocol_fail(ERR_USAGE, "SSL/TLS not supported in this build"); + (void)in; + (void)fd; +} diff --git a/scripts/nullmailer-log.run b/scripts/nullmailer-log.run new file mode 100644 index 0000000..3e69ddb --- /dev/null +++ b/scripts/nullmailer-log.run @@ -0,0 +1,2 @@ +#! /bin/sh +exec setuidgid nullmail multilog t /var/log/nullmailer diff --git a/scripts/nullmailer.run b/scripts/nullmailer.run new file mode 100644 index 0000000..7682f01 --- /dev/null +++ b/scripts/nullmailer.run @@ -0,0 +1,3 @@ +#! /bin/sh +exec 2>&1 +exec setuidgid nullmail /usr/sbin/nullmailer-send diff --git a/scripts/nullmailer.service b/scripts/nullmailer.service new file mode 100644 index 0000000..1412810 --- /dev/null +++ b/scripts/nullmailer.service @@ -0,0 +1,17 @@ +[Unit] +Description=Nullmailer relay-only MTA +Requires=network.target +After=local-fs.target +ConditionPathExists=/var/spool/nullmailer/queue +ConditionPathExists=/etc/nullmailer/defaultdomain +ConditionPathExists=/etc/nullmailer/me + +[Service] +WorkingDirectory=/var/spool/nullmailer +ExecStart=/usr/sbin/nullmailer-send +User=nullmail +Group=nullmail +Restart=always + +[Install] +WantedBy=multi-user.target @@ -0,0 +1,95 @@ +Name: nullmailer +Summary: Simple relay-only mail transport agent +Version: @VERSION@ +Release: 1 +License: GPL +Group: Networking/Daemons +Source: http://untroubled.org/nullmailer/archive/%{version}/nullmailer-%{version}.tar.gz +BuildRoot: /tmp/nullmailer-root +URL: http://untroubled.org/nullmailer/ +Packager: Bruce Guenter <bruce@untroubled.org> +Provides: smtpdaemon +Conflicts: sendmail +Conflicts: qmail +Requires: supervise-scripts >= 3.2 +Requires: gnutls +BuildRequires: gnutls-devel +Requires(pre,preun): shadow-utils + +%description +Nullmailer is a mail transport agent designed to only relay all its +messages through a fixed set of "upstream" hosts. It is also designed +to be secure. + +%prep +%setup + +%build +CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" \ +./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-tls + +make + +%install +rm -fr $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/etc +mkdir -p $RPM_BUILD_ROOT/usr/lib +mkdir -p $RPM_BUILD_ROOT/var/service/nullmailer/log +mkdir -p $RPM_BUILD_ROOT/var/log/nullmailer + +make DESTDIR=$RPM_BUILD_ROOT install-strip +ln -s ../sbin/sendmail $RPM_BUILD_ROOT/usr/lib/sendmail +install scripts/nullmailer.run $RPM_BUILD_ROOT/var/service/nullmailer/run +install scripts/nullmailer-log.run $RPM_BUILD_ROOT/var/service/nullmailer/log/run + +%clean +rm -rf $RPM_BUILD_ROOT + +%pre +PATH="/sbin:/usr/sbin:$PATH" export PATH +if [ "$1" = 1 ]; then + # pre-install instructions + grep ^nullmail: /etc/group >/dev/null || groupadd -r nullmail + grep ^nullmail: /etc/passwd >/dev/null || useradd -d /var/lock/svc/nullmailer -g nullmail -M -r -s /bin/true nullmail +fi + +%post +if ! [ -L /service/nullmailer ]; then + svc-add /var/service/nullmailer +fi +if ! [ -s /etc/nullmailer/me ]; then + /bin/hostname --fqdn >/etc/nullmailer/me +fi +if ! [ -s /etc/nullmailer/defaultdomain ]; then + /bin/hostname --domain >/etc/nullmailer/defaultdomain +fi + +%preun +if [ "$1" = 0 ]; then + svc-remove nullmailer +fi + +%postun +if [ "$1" = 0 ]; then + # post-erase instructions + /usr/sbin/userdel nullmail + /usr/sbin/groupdel nullmail +fi + +%files +%defattr(-,nullmail,nullmail) +%doc AUTHORS BUGS ChangeLog COPYING INSTALL NEWS README TODO doc/DIAGRAM +%dir /etc/nullmailer +%attr(04711,nullmail,nullmail) /usr/bin/mailq +/usr/bin/nullmailer-inject +/usr/bin/nullmailer-smtpd +/usr/lib/sendmail +%dir /usr/libexec/nullmailer +/usr/libexec/nullmailer/* +%{_mandir}/*/* +%attr(04711,nullmail,nullmail) /usr/sbin/nullmailer-queue +/usr/sbin/nullmailer-send +/usr/sbin/sendmail +%dir /var/log/nullmailer +/var/service/nullmailer +/var/spool/nullmailer diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..4a742c2 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,35 @@ +bin_PROGRAMS = \ + mailq \ + nullmailer-dsn \ + nullmailer-inject \ + nullmailer-smtpd +sbin_PROGRAMS = \ + nullmailer-queue \ + nullmailer-send \ + sendmail + +#noinst_PROGRAMS = address + +AM_CPPFLAGS = -I$(top_srcdir)/lib + +mailq_SOURCES = mailq.cc +mailq_LDADD = ../lib/libnullmailer.a + +nullmailer_dsn_SOURCES = dsn.cc +nullmailer_dsn_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a + +nullmailer_inject_SOURCES = inject.cc +nullmailer_inject_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a + +nullmailer_queue_SOURCES = queue.cc +nullmailer_queue_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a + +nullmailer_send_SOURCES = send.cc +nullmailer_send_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a + +nullmailer_smtpd_SOURCES = smtpd.cc +nullmailer_smtpd_LDADD = ../lib/libnullmailer.a + +sendmail_SOURCES = sendmail.cc +sendmail_LDADD = ../lib/cli++/libcli++.a ../lib/libnullmailer.a + diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..b84e585 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,691 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +bin_PROGRAMS = mailq$(EXEEXT) nullmailer-dsn$(EXEEXT) \ + nullmailer-inject$(EXEEXT) nullmailer-smtpd$(EXEEXT) +sbin_PROGRAMS = nullmailer-queue$(EXEEXT) nullmailer-send$(EXEEXT) \ + sendmail$(EXEEXT) +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" +PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) +am_mailq_OBJECTS = mailq.$(OBJEXT) +mailq_OBJECTS = $(am_mailq_OBJECTS) +mailq_DEPENDENCIES = ../lib/libnullmailer.a +am_nullmailer_dsn_OBJECTS = dsn.$(OBJEXT) +nullmailer_dsn_OBJECTS = $(am_nullmailer_dsn_OBJECTS) +nullmailer_dsn_DEPENDENCIES = ../lib/libnullmailer.a \ + ../lib/cli++/libcli++.a +am_nullmailer_inject_OBJECTS = inject.$(OBJEXT) +nullmailer_inject_OBJECTS = $(am_nullmailer_inject_OBJECTS) +nullmailer_inject_DEPENDENCIES = ../lib/libnullmailer.a \ + ../lib/cli++/libcli++.a +am_nullmailer_queue_OBJECTS = queue.$(OBJEXT) +nullmailer_queue_OBJECTS = $(am_nullmailer_queue_OBJECTS) +nullmailer_queue_DEPENDENCIES = ../lib/libnullmailer.a \ + ../lib/cli++/libcli++.a +am_nullmailer_send_OBJECTS = send.$(OBJEXT) +nullmailer_send_OBJECTS = $(am_nullmailer_send_OBJECTS) +nullmailer_send_DEPENDENCIES = ../lib/libnullmailer.a \ + ../lib/cli++/libcli++.a +am_nullmailer_smtpd_OBJECTS = smtpd.$(OBJEXT) +nullmailer_smtpd_OBJECTS = $(am_nullmailer_smtpd_OBJECTS) +nullmailer_smtpd_DEPENDENCIES = ../lib/libnullmailer.a +am_sendmail_OBJECTS = sendmail.$(OBJEXT) +sendmail_OBJECTS = $(am_sendmail_OBJECTS) +sendmail_DEPENDENCIES = ../lib/cli++/libcli++.a ../lib/libnullmailer.a +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(mailq_SOURCES) $(nullmailer_dsn_SOURCES) \ + $(nullmailer_inject_SOURCES) $(nullmailer_queue_SOURCES) \ + $(nullmailer_send_SOURCES) $(nullmailer_smtpd_SOURCES) \ + $(sendmail_SOURCES) +DIST_SOURCES = $(mailq_SOURCES) $(nullmailer_dsn_SOURCES) \ + $(nullmailer_inject_SOURCES) $(nullmailer_queue_SOURCES) \ + $(nullmailer_send_SOURCES) $(nullmailer_smtpd_SOURCES) \ + $(sendmail_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HAVE_GETADDRINFO = @HAVE_GETADDRINFO@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RM = @RM@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +#noinst_PROGRAMS = address +AM_CPPFLAGS = -I$(top_srcdir)/lib +mailq_SOURCES = mailq.cc +mailq_LDADD = ../lib/libnullmailer.a +nullmailer_dsn_SOURCES = dsn.cc +nullmailer_dsn_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a +nullmailer_inject_SOURCES = inject.cc +nullmailer_inject_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a +nullmailer_queue_SOURCES = queue.cc +nullmailer_queue_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a +nullmailer_send_SOURCES = send.cc +nullmailer_send_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a +nullmailer_smtpd_SOURCES = smtpd.cc +nullmailer_smtpd_LDADD = ../lib/libnullmailer.a +sendmail_SOURCES = sendmail.cc +sendmail_LDADD = ../lib/cli++/libcli++.a ../lib/libnullmailer.a +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) + +mailq$(EXEEXT): $(mailq_OBJECTS) $(mailq_DEPENDENCIES) $(EXTRA_mailq_DEPENDENCIES) + @rm -f mailq$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(mailq_OBJECTS) $(mailq_LDADD) $(LIBS) + +nullmailer-dsn$(EXEEXT): $(nullmailer_dsn_OBJECTS) $(nullmailer_dsn_DEPENDENCIES) $(EXTRA_nullmailer_dsn_DEPENDENCIES) + @rm -f nullmailer-dsn$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(nullmailer_dsn_OBJECTS) $(nullmailer_dsn_LDADD) $(LIBS) + +nullmailer-inject$(EXEEXT): $(nullmailer_inject_OBJECTS) $(nullmailer_inject_DEPENDENCIES) $(EXTRA_nullmailer_inject_DEPENDENCIES) + @rm -f nullmailer-inject$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(nullmailer_inject_OBJECTS) $(nullmailer_inject_LDADD) $(LIBS) + +nullmailer-queue$(EXEEXT): $(nullmailer_queue_OBJECTS) $(nullmailer_queue_DEPENDENCIES) $(EXTRA_nullmailer_queue_DEPENDENCIES) + @rm -f nullmailer-queue$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(nullmailer_queue_OBJECTS) $(nullmailer_queue_LDADD) $(LIBS) + +nullmailer-send$(EXEEXT): $(nullmailer_send_OBJECTS) $(nullmailer_send_DEPENDENCIES) $(EXTRA_nullmailer_send_DEPENDENCIES) + @rm -f nullmailer-send$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(nullmailer_send_OBJECTS) $(nullmailer_send_LDADD) $(LIBS) + +nullmailer-smtpd$(EXEEXT): $(nullmailer_smtpd_OBJECTS) $(nullmailer_smtpd_DEPENDENCIES) $(EXTRA_nullmailer_smtpd_DEPENDENCIES) + @rm -f nullmailer-smtpd$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(nullmailer_smtpd_OBJECTS) $(nullmailer_smtpd_LDADD) $(LIBS) + +sendmail$(EXEEXT): $(sendmail_OBJECTS) $(sendmail_DEPENDENCIES) $(EXTRA_sendmail_DEPENDENCIES) + @rm -f sendmail$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(sendmail_OBJECTS) $(sendmail_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inject.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mailq.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/queue.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/send.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendmail.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smtpd.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-sbinPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-sbinPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-sbinPROGRAMS \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-sbinPROGRAMS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/dsn.cc b/src/dsn.cc new file mode 100644 index 0000000..3e6bf25 --- /dev/null +++ b/src/dsn.cc @@ -0,0 +1,225 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include <sys/types.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <time.h> +#include <unistd.h> +#include "cli++/cli++.h" +#include "itoa.h" +#include "defines.h" +#include "list.h" +#include "mystring/mystring.h" +#include "fdbuf/fdbuf.h" +#include "canonicalize.h" +#include "configio.h" +#include "hostname.h" +#include "makefield.h" + +typedef list<mystring> slist; + +static time_t opt_timestamp = 0; +static time_t opt_last_attempt = 0; +static time_t opt_retry_until = 0; +static const char* opt_envelope_id = 0; +static const char* opt_status = 0; +static const char* opt_remote = 0; +static const char* opt_diagnostic_code = 0; +static int opt_lines = -1; +static bool opt_ddn = false; + +const char* cli_program = "nullmailer-dsn"; +const char* cli_help_prefix = +"Reformat a queued message into a delivery status notification (DSN)\n"; +const char* cli_help_suffix = +"\n" +"The status code must be in the form 4.#.# or 5.#.#. If the status\n" +"code starts with 4, a delivery delay notification is generated.\n"; +const char* cli_args_usage = "status-code < message"; +const int cli_args_min = 1; +const int cli_args_max = 1; +cli_option cli_options[] = { + { 0, "diagnostic-code", cli_option::string, 0, &opt_diagnostic_code, + "Diagnostic code message", 0 }, + { 0, "envelope-id", cli_option::string, 0, &opt_envelope_id, + "Original envelope ID", 0 }, + { 0, "last-attempt", cli_option::ulong, 0, &opt_last_attempt, + "UNIX timestamp of the last attempt", + "access time on the input message" }, + { 0, "orig-timestamp", cli_option::ulong, 0, &opt_timestamp, + "UNIX timestamp on the original message", + "ctime on the input message" }, + { 0, "remote", cli_option::string, 0, &opt_remote, + "Name of remote server", 0 }, + { 0, "retry-until", cli_option::ulong, 0, &opt_retry_until, + "UNIX timestamp of the (future) final attempt", 0 }, + { 0, "max-lines", cli_option::integer, 0, &opt_lines, + "Maximum number of lines of the original message to copy", "none" }, + {0, 0, cli_option::flag, 0, 0, 0, 0} +}; + +#define die1sys(MSG) do{ fout << "nullmailer-dsn: " << MSG << strerror(errno) << endl; exit(111); }while(0) +#define die1(MSG) do{ fout << "nullmailer-dsn: " << MSG << endl; exit(111); }while(0) + +static mystring sender; +static mystring bounceto; +static mystring doublebounceto; +static mystring line; +static slist recipients; + +static mystring idhost; +static const mystring boundary = make_boundary(); + +int cli_main(int, char* argv[]) +{ + struct stat msgstat; + if (fstat(0, &msgstat) < 0) + die1sys("Could not stat the source message"); + if (opt_timestamp == 0) + opt_timestamp = msgstat.st_ctime; + if (opt_last_attempt == 0) + opt_last_attempt = msgstat.st_atime; + opt_status = argv[0]; + if ((opt_status[0] != '4' && opt_status[0] != '5') + || opt_status[1] != '.' + || !isdigit(opt_status[2]) + || opt_status[3] != '.' + || !isdigit(opt_status[4]) + || opt_status[5] != '\0') + die1("Status must be in the format 4.#.# or 5.#.#"); + opt_ddn = opt_status[0] == '4'; + if (opt_lines < 0) { + config_readint("bouncelines", opt_lines); + if (opt_lines < 0) + opt_lines = 0; + } + + if (!config_read("doublebounceto", doublebounceto) + || !doublebounceto) + config_read("adminaddr", doublebounceto); + read_hostnames(); + if (!config_read("idhost", idhost)) + idhost = me; + else + canonicalize(idhost); + config_read("bounceto", bounceto); + + if (!fin.getline(sender)) + die1sys("Could not read sender address from message: "); + if (!sender && !doublebounceto) + die1("Nowhere to send double bounce"); + while (fin.getline(line)) { + if (!line) + break; + recipients.append(line); + } + if (recipients.count() == 0) + die1("No recipients were read from message"); + + if (!!sender) + // Bounces either go to the sender or bounceto, if configured + fout << '\n' << (!!bounceto ? bounceto : sender); + else + fout << "#@[]\n" << doublebounceto; + + fout << "\n" + "\n" + "From: Message Delivery Subsystem <MAILER-DAEMON@" << me << ">\n" + "To: <" << sender << ">\n" + "Subject: Returned mail: Could not send message\n" + "Date: " << make_date() << "\n" + "Message-Id: " << make_messageid(idhost) << "\n" + "MIME-Version: 1.0\n" + "Content-Type: multipart/report; report-type=delivery-status;\n" + "\tboundary=\"" << boundary << "\"\n"; + + /* Human readable text portion */ + fout << "\n" + "--" << boundary << "\n" + "Content-Type: text/plain; charset=us-ascii\n" + "\n" + "This is the nullmailer delivery system. The message attached below\n" + << (opt_ddn + ? "has not been" + : "could not be") + << " delivered to one or more of the intended recipients:\n" + "\n"; + for (slist::const_iter recipient(recipients); recipient; recipient++) + fout << "\t<" << (*recipient) << ">\n"; + if (opt_ddn) { + if (opt_retry_until > 0) + fout << "\nDelivery will continue to be attempted until " + << make_date(opt_retry_until) << '\n'; + fout << "\n" + "A final delivery status notification will be generated if delivery\n" + "proves to be impossible within the configured time limit.\n"; + } + + /* delivery-status portion */ + fout << "\n" + "--" << boundary << "\n" + "Content-Type: message/delivery-status\n" + "\n" + "Reporting-MTA: x-local-hostname; " << me << "\n" + "Arrival-Date: " << make_date(opt_timestamp) << "\n"; + if (opt_envelope_id != 0) + fout << "Original-Envelope-Id: " << opt_envelope_id << '\n'; + + for (slist::const_iter recipient(recipients); recipient; recipient++) { + fout << "\n" + "Final-Recipient: rfc822; " << (*recipient) << "\n" + "Action: " << (opt_ddn ? "delayed": "failed") << "\n" + "Status: " << opt_status << "\n" + "Last-Attempt-Date: " << make_date(opt_last_attempt) << '\n'; + if (opt_remote != 0) + fout << "Remote-MTA: dns; " << opt_remote << '\n'; + if (opt_diagnostic_code != 0) + fout << "Diagnostic-Code: " << opt_diagnostic_code << '\n'; + if (opt_ddn and opt_retry_until > 0) + fout << "Will-Retry-Until: " << make_date(opt_retry_until) << '\n'; + } + + // Copy the message + fout << "\n" + "--" << boundary << "\n" + "Content-Type: message/rfc822\n" + "\n"; + // Copy the header + while (fin.getline(line) && !!line) + fout << line << '\n'; + // Optionally copy the body + if (opt_lines) { + fout << '\n'; + for (int i = 0; (opt_lines < 0 || i < opt_lines) && fin.getline(line); i++) + fout << line << '\n'; + } + + fout << "\n" + "--" << boundary << "--\n"; + + return 0; +} diff --git a/src/inject.cc b/src/inject.cc new file mode 100644 index 0000000..b193fe9 --- /dev/null +++ b/src/inject.cc @@ -0,0 +1,552 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include "defines.h" +#include <ctype.h> +#include <errno.h> +#include <pwd.h> +#include <stdlib.h> +#include <string.h> +#include <sys/wait.h> +#include <unistd.h> +#include "mystring/mystring.h" +#include "list.h" +#include "hostname.h" +#include "fdbuf/fdbuf.h" +#include "itoa.h" +#include "address.h" +#include "canonicalize.h" +#include "configio.h" +#include "cli++/cli++.h" +#include "makefield.h" +#include "forkexec.h" + +enum { + use_args, use_both, use_either, use_header +}; +static int use_recips = use_either; +static int show_message = false; +static int show_envelope = false; +static const char* o_from = 0; + +const char* cli_program = "nullmailer-inject"; +const char* cli_help_prefix = "Reformat and inject a message into the nullmailer queue\n"; +const char* cli_help_suffix = ""; +const char* cli_args_usage = "[recipients] <message"; +const int cli_args_min = 0; +const int cli_args_max = -1; +cli_option cli_options[] = { + { 'a', "use-args", cli_option::flag, use_args, &use_recips, + "Use only command-line arguments for recipients", 0 }, + { 'b', "use-both", cli_option::flag, use_both, &use_recips, + "Use both command-line and message header for recipients", 0 }, + { 'e', "use-either", cli_option::flag, use_either, &use_recips, + "Use either command-line and message header for recipients", 0 }, + { 'h', "use-header", cli_option::flag, use_header, &use_recips, + "Use only message header for recipients", 0 }, + { 'f', "from", cli_option::string, 0, &o_from, + "Set the sender address", 0 }, + { 'n', "no-queue", cli_option::flag, 1, &show_message, + "Send the formatted message to standard output", 0 }, + { 'v', "show-envelope", cli_option::flag, 1, &show_envelope, + "Show the envelope with the message", 0 }, + {0, 0, cli_option::flag, 0, 0, 0, 0} +}; + +#define fail(MSG) do{ ferr << "nullmailer-inject: " << MSG << endl; return false; }while(0) +#define fail_sys(MSG) do{ ferr << "nullmailer-inject: " << MSG << ": " << strerror(errno) << endl; return false; }while(0) +#define bad_hdr(LINE,MSG) do{ header_has_errors = true; ferr << "nullmailer-inject: Invalid header line:\n " << LINE << "\n " MSG << endl; }while(0) + +typedef list<mystring> slist; +// static bool do_debug = false; + +static mystring cur_line; + +/////////////////////////////////////////////////////////////////////////////// +// Configuration +/////////////////////////////////////////////////////////////////////////////// +static mystring idhost; + +extern void canonicalize(mystring& domain); + +void read_config() +{ + mystring tmp; + read_hostnames(); + if(!config_read("idhost", idhost)) + idhost = me; + else + canonicalize(idhost); +} + +/////////////////////////////////////////////////////////////////////////////// +// Envelope processing +/////////////////////////////////////////////////////////////////////////////// +static slist recipients; +static mystring sender; +static bool use_header_recips = true; +static bool use_header_sender = true; + +void parse_recips(const mystring& list) +{ + if(!!list) { + int start = 0; + int end; + while((end = list.find_first('\n', start)) >= 0) { + recipients.append(list.sub(start, end-start)); + start = end+1; + } + } +} + +bool parse_recip_arg(mystring str) +{ + mystring list; + if(!parse_addresses(str, list)) + return false; + parse_recips(list); + return true; +} + +bool parse_sender(const mystring& list) +{ + int end = list.find_first('\n'); + if(end > 0 && list.find_first('\n', end+1) < 0) { + sender = list.sub(0, end); + return true; + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +// Header processing +/////////////////////////////////////////////////////////////////////////////// +static slist headers; + +static bool header_is_resent = false; +static bool header_has_errors = false; +static bool header_add_to = false; + +struct header_field +{ + // member information + const char* name; + unsigned length; + bool is_address; + bool is_recipient; + bool is_sender; + bool is_resent; + bool remove; // remove means strip after parsing + bool ignore; // ignore means do not parse + + bool present; + + bool parse(mystring& line, bool& rm) + { + if(strncasecmp(line.c_str(), name, length)) + return false; + rm = remove; + if(ignore) + return true; + if(is_resent) { + if(!header_is_resent) { + if(use_header_sender) + sender = ""; + if(use_header_recips) + recipients.empty(); + } + header_is_resent = true; + } + if(is_address) { + mystring tmp = line.right(length); + mystring list; + if(!parse_addresses(tmp, list)) + bad_hdr(line, "Unable to parse the addresses."); + else if(!tmp) { + rm = true; + return true; + } + else { + line = mystringjoin(name) + " " + tmp; + if(is_recipient) { + if(is_resent == header_is_resent && use_header_recips) + parse_recips(list); + } + else if(is_sender) { + if(is_resent == header_is_resent && use_header_sender) + parse_sender(list); + } + } + } + present = true; + return true; + } +}; + +#define F false +#define T true +#define X(N,IA,IR,IS,IRS,R) { #N ":",strlen(#N ":"),\ + IA,IR,IS,IRS,R,false, false } +static header_field header_fields[] = { + // Sender address fields, in order of priority + X(Sender, T,F,F,F,F), // 0 + X(From, T,F,F,F,F), // 1 + X(Reply-To, T,F,F,F,F), // 2 + X(Return-Path, T,F,T,F,T), // 3 + X(Return-Receipt-To, T,F,F,F,F), // 4 + X(Errors-To, T,F,F,F,F), // 5 + X(Resent-Sender, T,F,F,T,F), // 6 + X(Resent-From, T,F,F,T,F), // 7 + X(Resent-Reply-To, T,F,F,T,F), // 8 + // Destination address fields + X(To, T,T,F,F,F), // 9 + X(Cc, T,T,F,F,F), // 10 + X(Bcc, T,T,F,F,T), // 11 + X(Apparently-To, T,T,F,F,F), // 12 + X(Resent-To, T,T,F,T,F), // 13 + X(Resent-Cc, T,T,F,T,F), // 14 + X(Resent-Bcc, T,T,F,T,T), // 15 + // Other fields of interest + X(Date, F,F,F,F,F), // 16 + X(Message-Id, F,F,F,F,F), // 17 + X(Resent-Date, F,F,F,T,F), // 18 + X(Resent-Message-Id, F,F,F,T,F), // 19 + X(Content-Length, F,F,F,F,T), // 20 +}; +#undef X +#undef F +#undef T +#define header_field_count (sizeof header_fields/sizeof(header_field)) +static bool& header_has_from = header_fields[1].present; +static bool& header_has_rfrom = header_fields[7].present; +static bool& header_has_to = header_fields[9].present; +static bool& header_has_cc = header_fields[10].present; +static bool& header_has_rto = header_fields[13].present; +static bool& header_has_rcc = header_fields[14].present; +static bool& header_has_date = header_fields[16].present; +static bool& header_has_mid = header_fields[17].present; +static bool& header_has_rdate = header_fields[18].present; +static bool& header_has_rmid = header_fields[19].present; +static header_field& header_field_from = header_fields[1]; +static header_field& header_field_mid = header_fields[17]; +static header_field& header_field_rpath = header_fields[3]; + +static bool use_name_address_style = true; +static mystring from; + +void setup_from() +{ + mystring user = getenv("NULLMAILER_USER"); + if(!user) user = getenv("MAILUSER"); + if(!user) user = getenv("USER"); + if(!user) user = getenv("LOGNAME"); + if(!user) { + struct passwd *pw = getpwuid(getuid()); + if (pw) user = pw->pw_name; + } + if(!user) user = "unknown"; + + mystring host = getenv("NULLMAILER_HOST"); + if(!host) host = getenv("MAILHOST"); + if(!host) host = getenv("HOSTNAME"); + if(!host) host = defaulthost; + canonicalize(host); + + mystring name = getenv("NULLMAILER_NAME"); + if(!name) name = getenv("MAILNAME"); + if(!name) name = getenv("NAME"); + + if(use_name_address_style) { + if(!name) from = "<" + user + "@" + host + ">"; + else from = name + " <" + user + "@" + host + ">"; + } + else { + if(!name) from = user + "@" + host; + else from = user + "@" + host + " (" + name + ")"; + } + + mystring suser = getenv("NULLMAILER_SUSER"); + if(!suser) suser = user; + + mystring shost = getenv("NULLMAILER_SHOST"); + if(!shost) shost = host; + canonicalize(shost); + + if(use_header_sender && !sender) + sender = suser + "@" + shost; +} + +bool parse_line(mystring& line) +{ + bool valid = false; + for(unsigned i = 0; i < line.length(); i++) { + char ch = line[i]; + if(isspace(ch)) + break; + if(ch == ':') { + valid = (i > 0); + break; + } + } + if(!valid) + //bad_hdr(line, "Missing field name."); + return false; + bool remove = false; + for(unsigned i = 0; i < header_field_count; i++) { + header_field& h = header_fields[i]; + if(h.parse(line, remove)) + break; + } + if(!remove) + headers.append(line); + return true; +} + +bool is_header(const mystring& line) +{ + for(unsigned i = 0; i < line.length(); i++) { + char ch = line[i]; + if(isspace(ch)) + return false; + if(ch == ':') + return true; + } + return false; +} + +bool is_continuation(const mystring& line) +{ + return isspace(line[0]); +} + +bool read_header() +{ + mystring cur_line; + mystring whole; + bool first = true; + for (;;) { + if (!fin.getline(cur_line)) + cur_line = ""; + if(!cur_line || cur_line == "\r") + break; + // Ignore a leading RFC 976 "From " line mistakenly inserted by some programs. + if(first && (cur_line.starts_with("From ") || cur_line.starts_with(">From "))) + continue; + first = false; + if(!!whole && is_continuation(cur_line)) { + //if(!whole) + //bad_hdr(cur_line, "First line cannot be a continuation line."); + //else + whole += "\n" + cur_line; + } + else if(!is_header(cur_line)) { + cur_line += '\n'; + break; + } + else { + if(!!whole) + parse_line(whole); + whole = cur_line; + cur_line = ""; + } + } + if(!!whole) + parse_line(whole); + return !header_has_errors; +} + +mystring make_recipient_list() +{ + mystring result; + bool first = true; + for(slist::iter iter(recipients); iter; iter++) { + if(!first) + result = result + ", " + *iter; + else + result = *iter; + first = false; + } + return result; +} + +bool fix_header() +{ + setup_from(); + if(!header_is_resent) { + if(!header_has_date) + headers.append("Date: " + make_date()); + if(!header_has_mid) + headers.append("Message-Id: " + make_messageid(idhost)); + if(!header_has_from) + headers.append("From: " + from); + if(!header_has_to && !header_has_cc && header_add_to && + recipients.count() > 0) { + header_has_to = true; + headers.append("To: " + make_recipient_list()); + } + } + else { + if(!header_has_rdate) + headers.append("Resent-Date: " + make_date()); + if(!header_has_rmid) + headers.append("Resent-Message-Id: " + make_messageid(idhost)); + if(!header_has_rfrom) + headers.append("Resent-From: " + from); + if(!header_has_rto && !header_has_rcc && header_add_to && + recipients.count() > 0) { + header_has_rto = true; + headers.append("Resent-To: " + make_recipient_list()); + } + } + if(!header_has_to && !header_has_cc) + headers.append("Cc: recipient list not shown: ;"); + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// Message sending +/////////////////////////////////////////////////////////////////////////////// +bool send_env(fdobuf& out) +{ + if(!(out << sender << "\n")) + fail("Error sending sender to nullmailer-queue."); + for(slist::iter iter(recipients); iter; iter++) + if(!(out << *iter << "\n")) + fail("Error sending recipients to nullmailer-queue."); + if(!(out << endl)) + fail("Error sending recipients to nullmailer-queue."); + return true; +} + +bool send_header(fdobuf& out) +{ + for(slist::iter iter(headers); iter; iter++) + if(!(out << *iter << "\n")) + fail("Error sending header to nullmailer-queue."); + if(!(out << endl)) + fail("Error sending header to nullmailer-queue."); + return true; +} + +bool send_body(fdobuf& out) +{ + if(!(out << cur_line) || + !fdbuf_copy(fin, out)) + fail("Error sending message body to nullmailer-queue."); + return true; +} + +bool send_message_stdout() +{ + if(show_envelope) + send_env(fout); + send_header(fout); + send_body(fout); + return true; +} + +bool send_message_nqueue() +{ + queue_pipe nq; + autoclose wfd = nq.start(); + if (wfd < 0) + return false; + fdobuf nqout(wfd); + if (!send_env(nqout) || !send_header(nqout) || !send_body(nqout)) + return false; + nqout.flush(); + wfd.close(); + return nq.wait(); +} + +bool send_message() +{ + return show_message ? send_message_stdout() : send_message_nqueue(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Main +/////////////////////////////////////////////////////////////////////////////// +bool parse_flags() +{ + for(const char* flagstr = getenv("NULLMAILER_FLAGS"); + flagstr && *flagstr; flagstr++) { + switch(*flagstr) { + case 'c': use_name_address_style=false; break; + case 'f': header_field_from.ignore=header_field_from.remove=true; break; + case 'i': header_field_mid.ignore=header_field_mid.remove=true; break; + case 's': header_field_rpath.ignore=header_field_rpath.remove=true; break; + case 't': header_add_to = true; break; + default: + // Just ignore any flags we can't handle + break; + } + } + return true; +} + +bool parse_args(int argc, char* argv[]) +{ + if(!parse_flags()) + return false; + if(o_from) { + mystring list; + mystring tmp(o_from); + if(tmp == "" || tmp == "<>") + sender = ""; + else if(!parse_addresses(tmp, list) || + !parse_sender(list)) { + ferr << "nullmailer-inject: Invalid sender address: " << o_from << endl; + return false; + } + use_header_sender = false; + } + use_header_recips = (use_recips != use_args); + if(use_recips == use_header) + return true; + if(use_recips == use_either && argc > 0) + use_header_recips = false; + bool result = true; + for(int i = 0; i < argc; i++) { + if(!parse_recip_arg(argv[i])) { + ferr << "Invalid recipient: " << argv[i] << endl; + result = false; + } + } + return result; +} + +int cli_main(int argc, char* argv[]) +{ + read_config(); + if(!parse_args(argc, argv) || + !read_header() || + !fix_header()) + return 1; + if(recipients.count() == 0) { + ferr << "No recipients were listed." << endl; + return 1; + } + if(!send_message()) + return 1; + return 0; +} diff --git a/src/mailq.cc b/src/mailq.cc new file mode 100644 index 0000000..7a31200 --- /dev/null +++ b/src/mailq.cc @@ -0,0 +1,71 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include <dirent.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <time.h> +#include <unistd.h> +#include "configio.h" +#include "defines.h" +#include "fdbuf/fdbuf.h" +#include "itoa.h" +#include "mystring/mystring.h" + +#define fail(X) do{ fout << X << endl; return 1; }while(0) + +int main(int, char*[]) +{ + mystring line; + + mystring msg_dir = CONFIG_PATH(QUEUE, NULL, "queue"); + if(chdir(msg_dir.c_str())) + fail("Cannot change directory to queue."); + DIR* dir = opendir("."); + if(!dir) + fail("Cannot open queue directory."); + struct dirent* entry; + while((entry = readdir(dir)) != 0) { + const char* name = entry->d_name; + if(name[0] == '.') + continue; + time_t time = atoi(name); + char timebuf[100]; + strftime(timebuf, 100, "%Y-%m-%d %H:%M:%S ", localtime(&time)); + fout << timebuf; + struct stat statbuf; + if(stat(name, &statbuf) == -1) + fout << "?????"; + else + fout << itoa(statbuf.st_size); + fout << " bytes"; + fdibuf in(name); + if (in.getline(line)) { + fout << " from <" << line << '>'; + while (in.getline(line) && !!line) + fout << "\n to <" << line << '>'; + } + fout << endl; + } + closedir(dir); + return 0; +} diff --git a/src/queue.cc b/src/queue.cc new file mode 100644 index 0000000..ff5d936 --- /dev/null +++ b/src/queue.cc @@ -0,0 +1,204 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <sys/stat.h> +#include <time.h> +#include <unistd.h> +#include "autoclose.h" +#include "configio.h" +#include "itoa.h" +#include "defines.h" +#include "mystring/mystring.h" +#include "fdbuf/fdbuf.h" +#include "configio.h" +#include "hostname.h" + +const char* cli_program = "nullmailer-queue"; + +#define fail(MSG) do{ fout << "nullmailer-queue: " << MSG << endl; return false; }while(0) + +pid_t pid = getpid(); +uid_t uid = getuid(); +time_t timesecs = time(0); +mystring adminaddr; +mystring allmailfrom; + +static mystring trigger_path; +static mystring msg_dir; +static mystring tmp_dir; + +bool is_dir(const char* path) +{ + struct stat buf; + return !stat(path, &buf) && S_ISDIR(buf.st_mode); +} + +bool is_exist(const char* path) +{ + struct stat buf; + return !stat(path, &buf); +} + +int fsyncdir(const char* path) +{ + autoclose fd = open(path, O_RDONLY); + if(fd == -1) + return 0; + int result = fsync(fd); + if(result == -1 && errno != EIO) + result = 0; + return result; +} + +void trigger() +{ + autoclose fd = open(trigger_path.c_str(), O_WRONLY|O_NONBLOCK, 0666); + if(fd == -1) + return; + char x = 0; + write(fd, &x, 1); +} + +bool validate_addr(mystring& addr, bool recipient) +{ + int i = addr.find_last('@'); + if(i <= 0) + return false; + mystring hostname = addr.right(i+1); + if (recipient && !!adminaddr && (hostname == me || hostname == "localhost")) + addr = adminaddr; + else if (!recipient && !!allmailfrom) + addr = allmailfrom; + else if(hostname.find_first('.') < 0) + return false; + return true; +} + +bool copyenv(fdobuf& out) +{ + mystring str; + if(!fin.getline(str)) + fail("Could not read envelope sender."); + if(!!str && !validate_addr(str, false)) + fail("Envelope sender address is invalid."); + if(!(out << str << endl)) + fail("Could not write envelope sender."); + unsigned count=0; + while(fin.getline(str) && !!str) { + if(!validate_addr(str, true)) + fail("Envelope recipient address is invalid."); + if(!(out << str << endl)) + fail("Could not write envelope recipient."); + ++count; + } + if(count == 0) + fail("No envelope recipients read."); + if(!(out << "\n")) + fail("Could not write extra blank line to destination."); + return true; +} + +bool makereceived(fdobuf& out) +{ + mystring line("Received: (nullmailer pid "); + line += itoa(pid); + line += " invoked by uid "; + line += itoa(uid); + line += ");\n\t"; + char buf[100]; + if(!strftime(buf, 100, "%a, %d %b %Y %H:%M:%S -0000\n", gmtime(×ecs))) + fail("Error generating a date string."); + line += buf; + if(!(out << line)) + fail("Could not write received line to message."); + return true; +} + +bool dump(int fd) +{ + fdobuf out(fd); + if(!copyenv(out)) + return false; + if(!makereceived(out)) + return false; + if(!fdbuf_copy(fin, out)) + fail("Error copying the message to the queue file."); + if(!out.sync()) + fail("Error flushing the output file."); + if(!out.close()) + fail("Error closing the output file."); + return true; +} + +bool deliver() +{ + if(!is_dir(msg_dir.c_str()) || !is_dir(tmp_dir.c_str())) + fail("Installation error: queue directory is invalid."); + + // Notes: + // - temporary file name is unique to the currently running + // nullmailer-queue program + // - destination file name is unique to the system + // - if the temporary file previously existed, it did so because + // the previous nullmailer-queue process crashed, and it can be + // safely overwritten + const mystring pidstr = itoa(pid); + const mystring tmpfile = tmp_dir + pidstr; + const mystring newfile = msg_dir + itoa(timesecs) + "." + pidstr; + + int out = open(tmpfile.c_str(), O_CREAT|O_WRONLY|O_TRUNC, 0600); + if(out < 0) + fail("Could not open temporary file for writing"); + if(!dump(out)) { + unlink(tmpfile.c_str()); + return false; + } + if(link(tmpfile.c_str(), newfile.c_str())) + fail("Error linking the temp file to the new file."); + if(fsyncdir(msg_dir.c_str())) + fail("Error syncing the new directory."); + if(unlink(tmpfile.c_str())) + fail("Error unlinking the temp file."); + return true; +} + +int main(int, char*[]) +{ + trigger_path = CONFIG_PATH(QUEUE, NULL, "trigger"); + msg_dir = CONFIG_PATH(QUEUE, "queue", ""); + tmp_dir = CONFIG_PATH(QUEUE, "tmp", ""); + + umask(077); + if(config_read("adminaddr", adminaddr) && !!adminaddr) { + adminaddr = adminaddr.subst(',', '\n'); + read_hostnames(); + } + config_read("allmailfrom", allmailfrom); + + if(!deliver()) + return 1; + trigger(); + return 0; +} diff --git a/src/send.cc b/src/send.cc new file mode 100644 index 0000000..84ba96d --- /dev/null +++ b/src/send.cc @@ -0,0 +1,506 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include "ac/time.h" +#include "argparse.h" +#include "autoclose.h" +#include "configio.h" +#include "defines.h" +#include "errcodes.h" +#include "fdbuf/fdbuf.h" +#include "forkexec.h" +#include "hostname.h" +#include "itoa.h" +#include "list.h" +#include "selfpipe.h" +#include "setenv.h" + +const char* cli_program = "nullmailer-send"; + +selfpipe selfpipe; + +typedef enum { tempfail=-1, permfail=0, success=1 } tristate; + +struct message +{ + time_t timestamp; + mystring filename; +}; + +typedef list<mystring> slist; +typedef list<struct message> msglist; + +#define msg1(MSG) do{ fout << MSG << endl; }while(0) +#define msg2(MSG1,MSG2) do{ fout << MSG1 << MSG2 << endl; }while(0) +#define msg1sys(MSG) do{ fout << MSG << strerror(errno) << endl; }while(0) +#define fail(MSG) do { msg1(MSG); return false; } while(0) +#define fail2(MSG1,MSG2) do{ msg2(MSG1,MSG2); return false; }while(0) +#define fail1sys(MSG) do{ msg1sys(MSG); return false; }while(0) +#define tempfail1sys(MSG) do{ msg1sys(MSG); return tempfail; }while(0) + +static mystring trigger_path; +static mystring msg_dir; + +struct remote +{ + static const mystring default_proto; + + mystring host; + mystring proto; + mystring program; + mystring options; + remote(const slist& list); + ~remote(); +}; + +const mystring remote::default_proto = "smtp"; + +remote::remote(const slist& lst) +{ + slist::const_iter iter = lst; + host = *iter; + options = "host=" + host + "\n"; + ++iter; + if(!iter) + proto = default_proto; + else { + proto = *iter; + for(++iter; iter; ++iter) { + mystring option = *iter; + // Strip prefix "--" + if (option[0] == '-' && option[1] == '-') + option = option.right(2); + options += option; + options += '\n'; + } + } + options += '\n'; + program = CONFIG_PATH(PROTOCOLS, NULL, proto.c_str()); +} + +remote::~remote() { } + +typedef list<remote> rlist; + +static rlist remotes; +static int minpause = 60; +static int pausetime = minpause; +static int maxpause = 24*60*60; +static int sendtimeout = 60*60; +static int queuelifetime = 7*24*60*60; + +bool load_remotes() +{ + slist rtmp; + config_readlist("remotes", rtmp); + remotes.empty(); + for(slist::const_iter r(rtmp); r; r++) { + if((*r)[0] == '#') + continue; + arglist parts; + if (!parse_args(parts, *r)) + continue; + remotes.append(remote(parts)); + } + if (remotes.count() == 0) + fail("No remote hosts listed for delivery"); + return true; +} + +bool load_config() +{ + mystring hh; + + if (!config_read("helohost", hh)) + hh = me; + setenv("HELOHOST", hh.c_str(), 1); + + int oldminpause = minpause; + if(!config_readint("pausetime", minpause)) + minpause = 60; + if(!config_readint("maxpause", maxpause)) + maxpause = 24*60*60; + if(!config_readint("sendtimeout", sendtimeout)) + sendtimeout = 60*60; + if(!config_readint("queuelifetime", queuelifetime)) + queuelifetime = 7*24*60*60; + + if (minpause != oldminpause) + pausetime = minpause; + + return load_remotes(); +} + +static msglist messages; +static bool reload_messages = false; + +void catch_alrm(int) +{ + signal(SIGALRM, catch_alrm); + reload_messages = true; +} + +bool load_messages() +{ + reload_messages = false; + fout << "Rescanning queue." << endl; + DIR* dir = opendir("."); + if(!dir) + fail1sys("Cannot open queue directory: "); + messages.empty(); + struct dirent* entry; + while((entry = readdir(dir)) != 0) { + const char* name = entry->d_name; + if (name[0] == '.') + continue; + struct stat st; + if (stat(name, &st) < 0) { + fout << "Could not stat " << name << ", skipping." << endl; + continue; + } + struct message m = { st.st_mtime, name }; + messages.append(m); + } + closedir(dir); + return true; +} + +tristate catchsender(fork_exec& fp) +{ + for (;;) { + switch (selfpipe.waitsig(sendtimeout)) { + case 0: // timeout + fout << "Sending timed out, killing protocol" << endl; + fp.kill(SIGTERM); + selfpipe.waitsig(); // catch the signal from killing the child + return tempfail; + case -1: + msg1sys("Error waiting for the child signal: "); + return tempfail; + case SIGCHLD: + break; + default: + continue; + } + break; + } + + int status = fp.wait_status(); + if(status < 0) { + fout << "Error catching the child process return value: " + << strerror(errno) << endl; + return tempfail; + } + else { + if(WIFEXITED(status)) { + status = WEXITSTATUS(status); + if(status) { + fout << "Sending failed: " << errorstr(status) << endl; + return (status & ERR_PERMANENT_FLAG) ? permfail : tempfail; + } + else { + fout << "Sent file." << endl; + return success; + } + } + else { + fout << "Sending process crashed or was killed." << endl; + return tempfail; + } + } +} + +bool log_msg(mystring& filename, remote& remote, int fd) +{ + fout << "Starting delivery:" + << " host: " << remote.host + << " protocol: " << remote.proto + << " file: " << filename << endl; + fdibuf in(fd); + mystring line; + mystring msg; + if (in.getline(line, '\n')) { + msg = "From: <"; + msg += line; + msg += '>'; + bool has_to = false; + while (in.getline(line, '\n')) { + if (!line) + break; + msg += has_to ? ", " : " to: "; + has_to = true; + msg += '<'; + msg += line; + msg += '>'; + } + fout << msg << endl; + while (in.getline(line, '\n')) { + if (!line) + break; + if (line.left(11).lower() == "message-id:") + fout << line << endl; + } + lseek(fd, 0, SEEK_SET); + return true; + } + fout << endl << "Can't read message" << endl; + return false; +} + +static bool copy_output(int fd, mystring& output) +{ + output = ""; + char buf[256]; + ssize_t rd; + while ((rd = read(fd, buf, sizeof buf)) > 0) + output += mystring(buf, rd); + return rd == 0; +} + +tristate send_one(mystring filename, remote& remote, mystring& output) +{ + autoclose fd = open(filename.c_str(), O_RDONLY); + if(fd < 0) { + fout << "Can't open file '" << filename << "'" << endl; + return tempfail; + } + log_msg(filename, remote, fd); + + fork_exec fp(remote.proto.c_str()); + int redirs[] = { REDIRECT_PIPE_TO, REDIRECT_PIPE_FROM, REDIRECT_NONE, fd }; + if (!fp.start(remote.program.c_str(), 4, redirs)) + return tempfail; + + if (write(redirs[0], remote.options.c_str(), remote.options.length()) != (ssize_t)remote.options.length()) + fout << "Warning: Writing options to protocol failed" << endl; + close(redirs[0]); + + tristate result = catchsender(fp); + if (!copy_output(redirs[1], output)) + fout << "Warning: Could not read output from protocol" << endl; + close(redirs[1]); + return result; +} + +static void parse_output(const mystring& output, const remote& remote, mystring& status, mystring& diag) +{ + diag = remote.proto.upper(); + diag += "; "; + diag += output.strip(); + diag.subst('\n', '/'); + status = "5.0.0"; + for (unsigned i = 0; i < output.length()-5; i++) + if (isdigit(output[i]) + && output[i+1] == '.' + && isdigit(output[i+2]) + && output[i+3] == '.' + && isdigit(output[i+4])) { + status = output.sub(i, 5); + break; + } +} + +bool bounce_msg(const message& msg, const remote& remote, const mystring& output) +{ + mystring failed = "../failed/"; + failed += msg.filename; + fout << "Moving message " << msg.filename << " into failed" << endl; + if (rename(msg.filename.c_str(), failed.c_str()) == -1) { + fout << "Can't rename file: " << strerror(errno) << endl; + return false; + } + autoclose fd = open(failed.c_str(), O_RDONLY); + if (fd < 0) + fout << "Can't open file '" << failed << "' to create bounce message" << endl; + else { + fout << "Generating bounce for '" << msg.filename << "'" << endl; + queue_pipe qp; + autoclose pfd = qp.start(); + if (pfd > 0) { + mystring program = program_path("nullmailer-dsn"); + fork_exec dsn("nullmailer-dsn"); + int redirs[] = { fd, pfd }; + mystring status_code, diag_code; + parse_output(output, remote, status_code, diag_code); + const char* args[] = { program.c_str(), + "--last-attempt", itoa(time(NULL)), + "--remote", remote.host.c_str(), + "--diagnostic-code", diag_code.c_str(), + status_code.c_str(), NULL }; + dsn.start(args, 2, redirs); + // Everything else cleans up itself + } + } + return true; +} + +void send_all() +{ + if(!load_config()) { + fout << "Could not load the config" << endl; + return; + } + if(remotes.count() <= 0) { + fout << "No remote hosts listed for delivery"; + return; + } + if(messages.count() == 0) + return; + fout << "Starting delivery, " + << itoa(messages.count()) << " message(s) in queue." << endl; + mystring output; + for(rlist::iter remote(remotes); remote; remote++) { + msglist::iter msg(messages); + while(msg) { + switch (send_one((*msg).filename, *remote, output)) { + case tempfail: + if (time(0) - (*msg).timestamp > queuelifetime) { + if (bounce_msg(*msg, *remote, output)) { + messages.remove(msg); + continue; + } + } + msg++; + break; + case permfail: + if (bounce_msg(*msg, *remote, output)) + messages.remove(msg); + else + msg++; + break; + default: + if(unlink((*msg).filename.c_str()) == -1) { + fout << "Can't unlink file: " << strerror(errno) << endl; + msg++; + } + else + messages.remove(msg); + } + } + } + fout << "Delivery complete, " + << itoa(messages.count()) << " message(s) remain." << endl; +} + +static int trigger; +#ifdef NAMEDPIPEBUG +static int trigger2; +#endif + +bool open_trigger() +{ + trigger = open(trigger_path.c_str(), O_RDONLY|O_NONBLOCK); +#ifdef NAMEDPIPEBUG + trigger2 = open(trigger_path.c_str(), O_WRONLY|O_NONBLOCK); +#endif + if(trigger == -1) + fail1sys("Could not open trigger file: "); + return true; +} + +bool read_trigger() +{ + if(trigger != -1) { + char buf[1024]; + read(trigger, buf, sizeof buf); +#ifdef NAMEDPIPEBUG + close(trigger2); +#endif + close(trigger); + } + return open_trigger(); +} + +bool do_select() +{ + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(trigger, &readfds); + struct timeval timeout; + + if (messages.count() == 0) + pausetime = maxpause; + timeout.tv_sec = pausetime; + timeout.tv_usec = 0; + + pausetime *= 2; + if (pausetime > maxpause) + pausetime = maxpause; + + int s = select(trigger+1, &readfds, 0, 0, &timeout); + if(s == 1) { + fout << "Trigger pulled." << endl; + read_trigger(); + reload_messages = true; + pausetime = minpause; + } + else if(s == -1 && errno != EINTR) + fail1sys("Internal error in select: "); + else if(s == 0) + reload_messages = true; + if(reload_messages) + load_messages(); + return true; +} + +int main(int, char*[]) +{ + trigger_path = CONFIG_PATH(QUEUE, NULL, "trigger"); + msg_dir = CONFIG_PATH(QUEUE, NULL, "queue"); + + read_hostnames(); + + if(!selfpipe) { + fout << "Could not set up self-pipe." << endl; + return 1; + } + selfpipe.catchsig(SIGCHLD); + + if(!open_trigger()) + return 1; + if(chdir(msg_dir.c_str()) == -1) { + fout << "Could not chdir to queue message directory." << endl; + return 1; + } + + signal(SIGALRM, catch_alrm); + signal(SIGHUP, SIG_IGN); + load_config(); + load_messages(); + for(;;) { + send_all(); + if (minpause == 0) break; + do_select(); + } + return 0; +} diff --git a/src/sendmail.cc b/src/sendmail.cc new file mode 100644 index 0000000..1540024 --- /dev/null +++ b/src/sendmail.cc @@ -0,0 +1,144 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include "config.h" +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "configio.h" +#include "fdbuf/fdbuf.h" +#include "defines.h" +#include "forkexec.h" +#include "setenv.h" +#include "cli++/cli++.h" + +const char* cli_program = "sendmail"; +const char* cli_help_prefix = "Nullmailer sendmail emulator\n"; +const char* cli_help_suffix = 0; +const char* cli_args_usage = "[recipients] <message"; +const int cli_args_min = 0; +const int cli_args_max = -1; +const bool cli_only_long = true; + +enum mode { mode_normal, mode_mailq, mode_smtp }; + +static int o_dummyi; +static const char* o_dummys; +static const char* o_sender = 0; +static int o_mode = 0; +static char* o_from; +static int use_header = false; + +cli_option cli_options[] = { + { 'B', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + { 0, "bm", cli_option::flag, mode_normal, &o_mode, + "Read mail from standard input (default)", 0 }, + { 0, "bp", cli_option::flag, mode_mailq, &o_mode, + "List information about mail queue", 0 }, + { 0, "bs", cli_option::flag, mode_smtp, &o_mode, + "Handle SMTP commands on standard input", 0 }, + { 'C', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + { 'd', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + { 'F', 0, cli_option::string, 0, &o_sender, + "Set the full name of the sender", 0 }, + { 'f', 0, cli_option::string, 0, &o_from, + "Set the envelope sender address", 0 }, + { 'h', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + { 'i', 0, cli_option::flag, 0, &o_dummyi, "Ignored", 0 }, + { 'L', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + { 'm', 0, cli_option::flag, 0, &o_dummyi, "Ignored", 0 }, + { 'N', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + { 'n', 0, cli_option::flag, 0, &o_dummyi, "Ignored", 0 }, + { 'O', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + { 'o', 0, cli_option::string, 0, &o_dummys, "Set sendmail option, ignored", 0 }, + { 0, "em", cli_option::flag, 0, &o_dummyi, + "Ignored", 0 }, + { 0, "ep", cli_option::flag, 0, &o_dummyi, + "Ignored", 0 }, + { 0, "eq", cli_option::flag, 0, &o_dummyi, + "Ignored", 0 }, + { 'p', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + { 'q', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + { 'R', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + { 'r', 0, cli_option::string, 0, &o_from, + "An alternate and obsolete form of the -f flag", 0 }, + { 't', 0, cli_option::flag, 1, &use_header, + "Read message for recipients", 0 }, + { 'U', 0, cli_option::flag, 0, &o_dummyi, "Ignored", 0 }, + { 'V', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + { 'v', 0, cli_option::flag, 0, &o_dummyi, "Ignored", 0 }, + { 'X', 0, cli_option::string, 0, &o_dummys, "Ignored", 0 }, + CLI_OPTION_END +}; + +bool setenvelope(char* str) +{ + char* at = strchr(str, '@'); + if(at) { + *at = 0; + setenv("NULLMAILER_HOST", at+1, 1); + } + setenv("NULLMAILER_USER", str, 1); + return true; +} + +int do_exec(const char* program, const char* args[]) +{ + mystring path = program_path(program); + args[0] = path.c_str(); + execv(args[0], (char**)args); + ferr << "sendmail: Could not exec " << program << '.' << endl; + return 1; +} + +int cli_main(int argc, char* argv[]) +{ + const char* extra_args[argc + 5] = {0}; + int extra_argc = 1; + + switch (o_mode) { + case mode_smtp: + return do_exec("nullmailer-smtpd", extra_args); + case mode_mailq: + return do_exec("mailq", extra_args); + default: + + extra_args[extra_argc++] = use_header ? "-b" : "-e"; + + if(o_sender) + setenv("NULLMAILER_NAME", o_sender, 1); + if(o_from) { + if(!setenvelope(o_from)) + return -1; + + // pass along empty sender + if(o_from[0] == '\0' || (strcmp(o_from, "<>") == 0)) { + extra_args[extra_argc++] = "-f"; + extra_args[extra_argc++] = o_from; + } + } + + for(int i = 0; i < argc; i++) + extra_args[extra_argc++] = argv[i]; + + return do_exec("nullmailer-inject", extra_args); + } +} diff --git a/src/smtpd.cc b/src/smtpd.cc new file mode 100644 index 0000000..4f8e096 --- /dev/null +++ b/src/smtpd.cc @@ -0,0 +1,267 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2017 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <unistd.h> +#include "autoclose.h" +#include "defines.h" +#include "fdbuf/fdbuf.h" +#include "mystring/mystring.h" +#include "forkexec.h" + +static const char resp_data_ok[] = "354 End your message with a period on a line by itself"; +static const char resp_goodbye[] = "221 2.0.0 Good bye"; +static const char resp_help[] = "214 2.0.0 Help not available"; +static const char resp_mail_bad[] = "554 5.1.2 Sender invalid"; +static const char resp_mail_ok[] = "250 2.1.0 Sender accepted"; +static const char resp_need_param[] = "501 5.5.2 Syntax error, command requires a parameter"; +static const char resp_no_mail[] = "503 5.5.1 You must send a valid sender first"; +static const char resp_no_param[] = "501 5.5.2 Syntax error, no parameters allowed"; +static const char resp_no_queue[] = "451 4.3.0 Starting nullmailer-queue failed"; +static const char resp_no_rcpt[] = "503 5.5.1 You must send a valid recipient first"; +static const char resp_ok[] = "250 2.3.0 OK"; +static const char resp_queue_exiterr[] = "451 4.3.0 Error returned from nullmailer-queue"; +static const char resp_queue_ok[] = "250 2.6.0 Accepted message"; +static const char resp_queue_waiterr[] = "451 4.3.0 Error checking return status from nullmailer-queue"; +static const char resp_qwrite_err[] = "451 4.3.0 Write to nullmailer-queue failed"; +static const char resp_rcpt_bad[] = "554 5.1.2 Recipient invalid"; +static const char resp_rcpt_ok[] = "250 2.1.5 Recipient accepted"; +static const char resp_unimp[] = "500 5.5.1 Not implemented"; + +static mystring line; +static mystring sender; +static mystring recipients; + +extern const char cli_program[] = "nullmailer-smtpd"; + +static int readline() +{ + if (!fin.getline(line)) + return 0; + if (line.length() > 0 + && line[line.length()-1] == '\r') + line = line.left(line.length()-1); + return 1; +} + +static mystring parse_addr_arg(mystring& param) +{ + mystring addr; + unsigned i; + char term; + if ((i = param.find_first('<') + 1) > 0) + term = '>'; + else { + term = ' '; + if ((i = param.find_first(':') + 1) <= 0) + if ((i = param.find_first(' ') + 1) <= 0) + return 0; + while (i < param.length() && param[i] == ' ') + ++i; + } + for (bool quoted = false; i < param.length() && (quoted || param[i] != term); ++i) { + switch (param[i]) { + case '"': + quoted = !quoted; + break; + case '\\': + ++i; + // fall through + default: + addr += param[i]; + } + } + // strip source routing + if (addr[0] == '@' + && (i = addr.find_first(':')) > 0) + addr = addr.right(i+1); + + return addr + "\n"; +} + +static void do_reset(void) +{ + sender = ""; + recipients = ""; +} + +static bool respond(const char* msg) +{ + fout << msg << '\r' << endl; + return fout; +} + +static bool qwrite(int qfd, const char* data, size_t len) +{ + ssize_t wr; + while (len > 0) { + wr = write(qfd, data, len); + if (wr <= 0) + return false; + len -= wr; + data += wr; + } + return true; +} + +static bool DATA(mystring& param) +{ + if (!!param) + return respond(resp_no_param); + if (!sender) + return respond(resp_no_mail); + if (!recipients) + return respond(resp_no_rcpt); + + queue_pipe nq; + autoclose wfd = nq.start(); + if (wfd < 0) + return respond(resp_no_queue); + if (!qwrite(wfd, sender.c_str(), sender.length()) + || !qwrite(wfd, recipients.c_str(), recipients.length()) + || !qwrite(wfd, "\n", 1)) + return respond(resp_qwrite_err); + + if (!respond(resp_data_ok)) + return false; + + while (readline()) { + if (line.length() == 1 && line[0] == '.') + break; + if (line.length() > 1 && line[0] == '.') + line = line.sub(1, line.length() - 1); + line += '\n'; + if (!qwrite(wfd, line.c_str(), line.length())) + return respond(resp_qwrite_err); + } + wfd.close(); + + return respond(nq.wait() ? resp_queue_ok : resp_queue_exiterr); +} + +static bool HELO(mystring& param) +{ + if (!param) + return respond(resp_need_param); + return respond(resp_ok); +} + +static bool HELP(mystring&) +{ + return respond(resp_help); +} + +static bool MAIL(mystring& param) +{ + if (!param) + return respond(resp_need_param); + do_reset(); + sender = parse_addr_arg(param); + return respond(!sender ? resp_mail_bad : resp_mail_ok); +} + +static bool NOOP(mystring&) +{ + return respond(resp_ok); +} + +static bool QUIT(mystring&) +{ + respond(resp_goodbye); + return false; +} + +static bool RCPT(mystring& param) +{ + if (!param) + return respond(resp_need_param); + if (!sender) + return respond(resp_no_mail); + mystring tmp = parse_addr_arg(param); + recipients += tmp; + return respond(!tmp ? resp_rcpt_bad : resp_rcpt_ok); +} + +static bool RSET(mystring&) +{ + do_reset(); + return respond(resp_ok); +} + +static bool VRFY(mystring&) +{ + return respond(resp_unimp); +} + +typedef bool (*dispatch_fn)(mystring& param); +struct dispatch +{ + const char* cmd; + dispatch_fn fn; +}; +static struct dispatch dispatch_table[] = { + { "DATA", DATA }, + { "EHLO", HELO }, + { "HELO", HELO }, + { "HELP", HELP }, + { "MAIL", MAIL }, + { "NOOP", NOOP }, + { "QUIT", QUIT }, + { "RCPT", RCPT }, + { "RSET", RSET }, + { "VRFY", VRFY }, + { 0, 0 } +}; + +static bool dispatch() +{ + mystring cmd; + mystring param; + cmd = line; + for (size_t i = 0; i < line.length(); i++) { + if (line[i] == ' ') { + cmd = line.left(i); + param = line.right(i+1).lstrip(); + break; + } + } + cmd = cmd.upper(); + struct dispatch* d; + for (d = dispatch_table; d->cmd != 0; d++) { + if (cmd == d->cmd) + return d->fn(param); + } + return respond("500 5.5.1 Not implemented"); +} + +int main(void) +{ + mystring line; + if (!respond("220 nullmailer-smtpd ready")) + return 0; + while (readline()) { + if (!dispatch()) + return 0; + } + return 0; +} diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..6a062cb --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,35 @@ +noinst_PROGRAMS = address-test argparse-test clitest0 clitest1 +EXTRA_DIST = address-trace.cc clitest.cc clitest.sh functions.in runtests \ + accept-qmqp.sh accept-smtp.sh +noinst_SCRIPTS = functions +CLEANFILES = functions + +AM_CPPFLAGS = -I$(top_srcdir)/lib + +address_test_SOURCES = address-test.cc # address-trace.cc +address_test_LDADD = ../lib/libnullmailer.a + +argparse_test_SOURCES = argparse-test.cc +argparse_test_LDADD = ../lib/libnullmailer.a + +clitest0_CPPFLAGS = $(AM_CPPFLAGS) -DCLI_ONLY_LONG=false +clitest0_SOURCES = clitest.cc +clitest0_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a + +clitest1_CPPFLAGS = $(AM_CPPFLAGS) -DCLI_ONLY_LONG=true +clitest1_SOURCES = clitest.cc +clitest1_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a + +functions: functions.in Makefile + sed -e 's,[@]SRCDIR[@],$(abs_top_srcdir),g; s,[@]BUILDDIR[@],$(abs_top_builddir),g;' < $< > $@ + +# The following makes sure that we can't produce a package without the +# tests executing properly +dist-hook: + cp -r $(srcdir)/tests $(distdir) + +check: all + ./address-test + ./argparse-test + sh $(srcdir)/clitest.sh + $(srcdir)/runtests `find $(abs_srcdir)/tests -type f -not -name '.*'` diff --git a/test/Makefile.in b/test/Makefile.in new file mode 100644 index 0000000..9e0d80c --- /dev/null +++ b/test/Makefile.in @@ -0,0 +1,620 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +noinst_PROGRAMS = address-test$(EXEEXT) argparse-test$(EXEEXT) \ + clitest0$(EXEEXT) clitest1$(EXEEXT) +subdir = test +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_address_test_OBJECTS = address-test.$(OBJEXT) +address_test_OBJECTS = $(am_address_test_OBJECTS) +address_test_DEPENDENCIES = ../lib/libnullmailer.a +am_argparse_test_OBJECTS = argparse-test.$(OBJEXT) +argparse_test_OBJECTS = $(am_argparse_test_OBJECTS) +argparse_test_DEPENDENCIES = ../lib/libnullmailer.a +am_clitest0_OBJECTS = clitest0-clitest.$(OBJEXT) +clitest0_OBJECTS = $(am_clitest0_OBJECTS) +clitest0_DEPENDENCIES = ../lib/libnullmailer.a ../lib/cli++/libcli++.a +am_clitest1_OBJECTS = clitest1-clitest.$(OBJEXT) +clitest1_OBJECTS = $(am_clitest1_OBJECTS) +clitest1_DEPENDENCIES = ../lib/libnullmailer.a ../lib/cli++/libcli++.a +SCRIPTS = $(noinst_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(address_test_SOURCES) $(argparse_test_SOURCES) \ + $(clitest0_SOURCES) $(clitest1_SOURCES) +DIST_SOURCES = $(address_test_SOURCES) $(argparse_test_SOURCES) \ + $(clitest0_SOURCES) $(clitest1_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HAVE_GETADDRINFO = @HAVE_GETADDRINFO@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RM = @RM@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = address-trace.cc clitest.cc clitest.sh functions.in runtests \ + accept-qmqp.sh accept-smtp.sh + +noinst_SCRIPTS = functions +CLEANFILES = functions +AM_CPPFLAGS = -I$(top_srcdir)/lib +address_test_SOURCES = address-test.cc # address-trace.cc +address_test_LDADD = ../lib/libnullmailer.a +argparse_test_SOURCES = argparse-test.cc +argparse_test_LDADD = ../lib/libnullmailer.a +clitest0_CPPFLAGS = $(AM_CPPFLAGS) -DCLI_ONLY_LONG=false +clitest0_SOURCES = clitest.cc +clitest0_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a +clitest1_CPPFLAGS = $(AM_CPPFLAGS) -DCLI_ONLY_LONG=true +clitest1_SOURCES = clitest.cc +clitest1_LDADD = ../lib/libnullmailer.a ../lib/cli++/libcli++.a +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu test/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +address-test$(EXEEXT): $(address_test_OBJECTS) $(address_test_DEPENDENCIES) $(EXTRA_address_test_DEPENDENCIES) + @rm -f address-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(address_test_OBJECTS) $(address_test_LDADD) $(LIBS) + +argparse-test$(EXEEXT): $(argparse_test_OBJECTS) $(argparse_test_DEPENDENCIES) $(EXTRA_argparse_test_DEPENDENCIES) + @rm -f argparse-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(argparse_test_OBJECTS) $(argparse_test_LDADD) $(LIBS) + +clitest0$(EXEEXT): $(clitest0_OBJECTS) $(clitest0_DEPENDENCIES) $(EXTRA_clitest0_DEPENDENCIES) + @rm -f clitest0$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(clitest0_OBJECTS) $(clitest0_LDADD) $(LIBS) + +clitest1$(EXEEXT): $(clitest1_OBJECTS) $(clitest1_DEPENDENCIES) $(EXTRA_clitest1_DEPENDENCIES) + @rm -f clitest1$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(clitest1_OBJECTS) $(clitest1_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/address-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argparse-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clitest0-clitest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clitest1-clitest.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +clitest0-clitest.o: clitest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clitest0_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT clitest0-clitest.o -MD -MP -MF $(DEPDIR)/clitest0-clitest.Tpo -c -o clitest0-clitest.o `test -f 'clitest.cc' || echo '$(srcdir)/'`clitest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/clitest0-clitest.Tpo $(DEPDIR)/clitest0-clitest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='clitest.cc' object='clitest0-clitest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clitest0_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o clitest0-clitest.o `test -f 'clitest.cc' || echo '$(srcdir)/'`clitest.cc + +clitest0-clitest.obj: clitest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clitest0_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT clitest0-clitest.obj -MD -MP -MF $(DEPDIR)/clitest0-clitest.Tpo -c -o clitest0-clitest.obj `if test -f 'clitest.cc'; then $(CYGPATH_W) 'clitest.cc'; else $(CYGPATH_W) '$(srcdir)/clitest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/clitest0-clitest.Tpo $(DEPDIR)/clitest0-clitest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='clitest.cc' object='clitest0-clitest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clitest0_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o clitest0-clitest.obj `if test -f 'clitest.cc'; then $(CYGPATH_W) 'clitest.cc'; else $(CYGPATH_W) '$(srcdir)/clitest.cc'; fi` + +clitest1-clitest.o: clitest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clitest1_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT clitest1-clitest.o -MD -MP -MF $(DEPDIR)/clitest1-clitest.Tpo -c -o clitest1-clitest.o `test -f 'clitest.cc' || echo '$(srcdir)/'`clitest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/clitest1-clitest.Tpo $(DEPDIR)/clitest1-clitest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='clitest.cc' object='clitest1-clitest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clitest1_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o clitest1-clitest.o `test -f 'clitest.cc' || echo '$(srcdir)/'`clitest.cc + +clitest1-clitest.obj: clitest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clitest1_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT clitest1-clitest.obj -MD -MP -MF $(DEPDIR)/clitest1-clitest.Tpo -c -o clitest1-clitest.obj `if test -f 'clitest.cc'; then $(CYGPATH_W) 'clitest.cc'; else $(CYGPATH_W) '$(srcdir)/clitest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/clitest1-clitest.Tpo $(DEPDIR)/clitest1-clitest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='clitest.cc' object='clitest1-clitest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(clitest1_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o clitest1-clitest.obj `if test -f 'clitest.cc'; then $(CYGPATH_W) 'clitest.cc'; else $(CYGPATH_W) '$(srcdir)/clitest.cc'; fi` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(SCRIPTS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-noinstPROGRAMS cscopelist-am ctags ctags-am dist-hook \ + distclean distclean-compile distclean-generic distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +functions: functions.in Makefile + sed -e 's,[@]SRCDIR[@],$(abs_top_srcdir),g; s,[@]BUILDDIR[@],$(abs_top_builddir),g;' < $< > $@ + +# The following makes sure that we can't produce a package without the +# tests executing properly +dist-hook: + cp -r $(srcdir)/tests $(distdir) + +check: all + ./address-test + ./argparse-test + sh $(srcdir)/clitest.sh + $(srcdir)/runtests `find $(abs_srcdir)/tests -type f -not -name '.*'` + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/test/accept-qmqp.sh b/test/accept-qmqp.sh new file mode 100644 index 0000000..8c36613 --- /dev/null +++ b/test/accept-qmqp.sh @@ -0,0 +1 @@ +echo '3:KOK,' diff --git a/test/accept-smtp.sh b/test/accept-smtp.sh new file mode 100644 index 0000000..541c375 --- /dev/null +++ b/test/accept-smtp.sh @@ -0,0 +1,7 @@ +echo 250 OK +echo 250 OK +echo 250 OK +echo 250 OK +echo 351 OK +echo 220 OK +sleep 1 diff --git a/test/address-test.cc b/test/address-test.cc new file mode 100644 index 0000000..57652bb --- /dev/null +++ b/test/address-test.cc @@ -0,0 +1,216 @@ +#include "config.h" +#include <ctype.h> +#include "canonicalize.h" +#include "mystring/mystring.h" +#include "address.h" + +#include "fdbuf/fdbuf.h" +#include "itoa.h" + +static bool test(const mystring& in, + const mystring& out, + const mystring& list) +{ + mystring line = in; + mystring tmplist; + if(!parse_addresses(line, tmplist)) { + fout << "Parsing of '" << in << "' failed." << endl; + return false; + } + bool status = true; + if(!!list && tmplist != list) { + fout << "Parsing of '" << in << "' failed: bad result list, was:\n" + << tmplist + << "should be:\n" + << list; + status = false; + } + if(!!out && line != out) { + fout << "Parsing of '" << in << "' failed: bad result string, was:\n" + << line + << "\nshould be:\n" + << out << "\n"; + status = false; + } + return status; +} + +#define TEST(X,Y,Z) do{ ++count; if(!test(X,Y,Z)) ++failed; }while(0) + +mystring defaulthost = "a"; +mystring defaultdomain = "b.c"; + +int main() +{ + int count = 0; + int failed = 0; + // empty list + TEST("", + "", + ""); + // empty list with comment + TEST("(no addresses)", + "(no addresses)", + ""); + // periods in local + TEST("a.b@c.d", + "a.b@c.d", + "a.b@c.d\n"); + // quoted local + TEST("\"e\"@c.d", + "e@c.d", + "e@c.d\n"); + // missing host and domain + TEST("e", + "e@a.b.c", + "e@a.b.c\n"); + // missing domain + TEST("e@x", + "e@x.b.c", + "e@x.b.c\n"); + // trailing period + TEST("e@c.d.", + "e@c.d.", + "e@c.d.\n"); + // trailing period, single domain + TEST("e@c.", + "e@c.", + "e@c.\n"); + // comment <address> style + TEST("x<y@a.b>", + "x <y@a.b>", + "y@a.b\n"); + TEST("<y@a.b>", + "<y@a.b>", + "y@a.b\n"); + // address (comment) style + TEST("y@a.b(x)", + "y@a.b (x)", + "y@a.b\n"); + // internal comments before local + TEST("(j)y@a.b", + "y@a.b (j)", + "y@a.b\n"); + // internal comments after local + TEST("y(j)@a.b", + "y@a.b (j)", + "y@a.b\n"); + // internal comments before domain + TEST("y@(j)a.b", + "y@a.b (j)", + "y@a.b\n"); + // internal comments before period + TEST("y@a(j).b", + "y@a.b (j)", + "y@a.b\n"); + // internal comments after period + TEST("y@a.(j)b", + "y@a.b (j)", + "y@a.b\n"); + // normal list + TEST("a@b.c,d@e.f", + "a@b.c, d@e.f", + "a@b.c\nd@e.f\n"); + // list with comments + TEST("a@b.c(j),d@e.f(k)", + "a@b.c (j), d@e.f (k)", + "a@b.c\nd@e.f\n"); + // list without commas + TEST("a@b.c d@e.f", + "a@b.c, d@e.f", + "a@b.c\nd@e.f\n"); + // list without commas with comments + TEST("a@b.c(j) d@e.f(k)", + "a@b.c (j), d@e.f (k)", + "a@b.c\nd@e.f\n"); + // simple group + TEST("g: a@b.c, d@e.f;", + "g: a@b.c, d@e.f;", + "a@b.c\nd@e.f\n"); + // group with spaces in name + TEST("g h: a@b.c, d@e.f;", + "g h: a@b.c, d@e.f;", + "a@b.c\nd@e.f\n"); + // empty group + TEST("g: ;", + "g: ;", + ""); + // group with a comment + TEST("g: a@b.c(j);", + "g: a@b.c (j);", + "a@b.c\n"); + // group with comments + TEST("g:a@b.c(j),d@e.f(k);", + "g: a@b.c (j), d@e.f (k);", + "a@b.c\nd@e.f\n"); + // group with no commas + TEST("g:a@b.c d@e.f;", + "g: a@b.c, d@e.f;", + "a@b.c\nd@e.f\n"); + // group with route addresses + TEST("g:foo<a@b.c>;", + "g: foo <a@b.c>;", + "a@b.c\n"); + // route-path syntax (stripped) + TEST("f<@g.h:a@b.c>", + "f <a@b.c>", + "a@b.c\n"); + // multiple route-path syntax + TEST("f<@g.h@i.j:a@b.c>", + "f <a@b.c>", + "a@b.c\n"); + // comments with quoted brackets + TEST("(f\\)\\()a@b.c", + "a@b.c (f\\)\\()", + "a@b.c\n"); + // nested comments + TEST("(f(g)h)a@b.c", + "a@b.c (f(g)h)", + "a@b.c\n"); + // simple quoted addresses + TEST("\"a\"@b.c", + "a@b.c", + "a@b.c\n"); + // quoted parts of address + TEST("a.\"b\".c@d.e", + "a.b.c@d.e", + "a.b.c@d.e\n"); + // escaped characters within quotes + TEST("\"s\\'b\"@d.e", + "s'b@d.e", + "s'b@d.e\n"); + // escaped specials + TEST("\"s\\\"a\\\"b\"@d.e", + "\"s\\\"a\\\"b\"@d.e", + "s\"a\"b@d.e\n"); + // twisted syntax + //TEST("\"\\\"d\\\" <\"<@_._:e@f.g>", + // "who knows", + // "e@f.g\n"); + TEST("c@d.e (a.b)", + "c@d.e (a.b)", + "c@d.e\n"); + TEST("\"a.b\" <c@d.e>", + "\"a.b\" <c@d.e>", + "c@d.e\n"); + TEST("Mr. T <c@d.e>", + "Mr. T <c@d.e>", + "c@d.e\n"); + TEST("a.b <c@d.e>", + "a.b <c@d.e>", + "c@d.e\n"); + TEST("Mr . and T <c@d.e>", + "Mr . and T <c@d.e>", + "c@d.e\n"); + // Whitespace in the quoted string + TEST("\"\n f\n \" <a@b.c>", + "f <a@b.c>", + "a@b.c\n"); + TEST("\" a.b\" <c@d.e>", + "\"a.b\" <c@d.e>", + "c@d.e\n"); + + fout << itoa(count) << " tests run, "; + fout << itoa(failed) << " failed." << endl; + return failed; +} diff --git a/test/address-trace.cc b/test/address-trace.cc new file mode 100644 index 0000000..f9957db --- /dev/null +++ b/test/address-trace.cc @@ -0,0 +1,2 @@ +#define TRACE +#include "address.cc" diff --git a/test/argparse-test.cc b/test/argparse-test.cc new file mode 100644 index 0000000..d37bda6 --- /dev/null +++ b/test/argparse-test.cc @@ -0,0 +1,51 @@ +#include "argparse.h" + +#include "fdbuf/fdbuf.h" +#include "itoa.h" + +static bool doit(const char* teststr, unsigned count, const char** result) +{ + arglist args; + unsigned c = parse_args(args, teststr); + if (c != count) { + fout << "Parsing of \"" << teststr << "\" failed, wrong count, was: " << c << " should be: " << count << endl; + return false; + } + arglist::const_iter iter(args); + for (unsigned i = 0; i < c; i++, iter++) { + if (*iter != result[i]) { + fout << "Parsing of \"" << teststr << "\" failed, wrong string, was:\n" + << *iter << " should be:\n" << result[i] << endl; + return false; + } + } + return true; +} + +#define TEST(X,Y,...) do{ const char* result[] = {__VA_ARGS__}; ++count; if (!doit(X, Y, result)) ++failed; } while(0) + +int main() +{ + int count = 0; + int failed = 0; + + TEST("", 0); + + TEST("one", 1, "one"); // Simple case + TEST(" two", 1, "two"); // Leading space + TEST("three ", 1, "three"); // Trailing space + TEST("one\\ two", 1, "one two"); // Escaped internal space + TEST(" one two three ", 3, "one","two","three"); // Spaces between args + TEST("'one'", 1, "one"); // Simple single quoted + TEST("'one two'", 1, "one two"); // Single quoted with space + TEST("'one\\'two", 1, "one\\two"); // Single quoted with backslash + TEST("\"one two\"", 1, "one two"); // Double quoted + TEST(" one \"two\"three four", 3, "one", "twothree", "four"); // Mixed quoted and unquoted + TEST("\"one\\\" two\"", 1, "one\" two"); // Double quoted with escaped quote + TEST("one='two three' four", 2, "one=two three", "four"); // Single quotes within an arg with multiple args + TEST("one=\"two three\" four", 2, "one=two three", "four"); // Double quotes within an arg with multiple args + + fout << itoa(count) << " tests run, "; + fout << itoa(failed) << " failed." << endl; + return failed; +} diff --git a/test/clitest.cc b/test/clitest.cc new file mode 100644 index 0000000..c819972 --- /dev/null +++ b/test/clitest.cc @@ -0,0 +1,45 @@ +#include "cli++/cli++.h" +#include "fdbuf/fdbuf.h" + +const char* cli_program = "clitest"; +const char* cli_help_prefix = "Nullmailer CLI test harness\n"; +const char* cli_help_suffix = 0; +const char* cli_args_usage = "[args]"; +const int cli_args_min = 0; +const int cli_args_max = -1; +const bool cli_only_long = CLI_ONLY_LONG; + +static int a = 0; +static int b = 0; +static const char* c = 0; +static const char* d = 0; + +cli_option cli_options[] = { + { 'a', 0, cli_option::flag, 1, &a, "Test flag", 0 }, + { 0, "bb", cli_option::flag, 1, &b, "Test flag", 0 }, + { 'c', 0, cli_option::string, 1, &c, "Test string", 0 }, + { 0, "dd", cli_option::string, 1, &d, "Test string", 0 }, + CLI_OPTION_END +}; + +static void showcstr(const char* name, const char* value) +{ + fout << ' ' << name; + if (value == NULL) + fout << "=NULL"; + else + fout << "=\"" << value << "\""; +} + +int cli_main(int argc, char* argv[]) +{ + fout << "argc=" << argc + << " a=" << a + << " b=" << b; + showcstr("c", c); + showcstr("d", d); + fout << endl; + for (int i = 0; i < argc; i++) + fout << "argv[" << i << "]=\"" << argv[i] << "\"" << endl; + return 0; +} diff --git a/test/clitest.sh b/test/clitest.sh new file mode 100644 index 0000000..a60133b --- /dev/null +++ b/test/clitest.sh @@ -0,0 +1,81 @@ +tmp=$PWD/clitest.tmp +trap 'rm -f ${tmp}*' EXIT + +testit() { + test "x$1" = 'x!' && isfailed='-eq 0' || isfailed='-ne 0' + "$@" >$tmp.out 2>/dev/null + if [ $? $isfailed ] + then + echo "Test \"$*\" failed!" + exit 1 + fi + if [ "x$1" != 'x!' ] + then + cat >$tmp.exp + if ! diff -u $tmp.exp $tmp.out + then + echo "Test \"$*\" failed!" + exit 1 + fi + fi +} + +testit ./clitest0 <<EOF +argc=0 a=0 b=0 c=NULL d=NULL +EOF +testit ./clitest1 <<EOF +argc=0 a=0 b=0 c=NULL d=NULL +EOF + +testit ! ./clitest0 -abb +testit ! ./clitest1 -abb + +testit ! ./clitest0 -a -bb +testit ./clitest1 -a -bb <<EOF +argc=0 a=1 b=1 c=NULL d=NULL +EOF + +testit ./clitest0 -a --bb <<EOF +argc=0 a=1 b=1 c=NULL d=NULL +EOF +testit ./clitest1 -a --bb <<EOF +argc=0 a=1 b=1 c=NULL d=NULL +EOF + +testit ./clitest0 -ctest <<EOF +argc=0 a=0 b=0 c="test" d=NULL +EOF +testit ./clitest1 -ctest <<EOF +argc=0 a=0 b=0 c="test" d=NULL +EOF + +testit ! ./clitest0 -ddtest +testit ! ./clitest1 -ddtest +testit ! ./clitest0 --ddtest +testit ! ./clitest1 --ddtest + +testit ! ./clitest0 -dd test +testit ./clitest1 -dd test <<EOF +argc=0 a=0 b=0 c=NULL d="test" +EOF + +testit ./clitest0 --dd test <<EOF +argc=0 a=0 b=0 c=NULL d="test" +EOF +testit ./clitest1 --dd test <<EOF +argc=0 a=0 b=0 c=NULL d="test" +EOF + +testit ! ./clitest0 -dd=test +testit ./clitest1 -dd=test <<EOF +argc=0 a=0 b=0 c=NULL d="test" +EOF + +testit ./clitest0 --dd=test <<EOF +argc=0 a=0 b=0 c=NULL d="test" +EOF +testit ./clitest1 --dd=test <<EOF +argc=0 a=0 b=0 c=NULL d="test" +EOF + +echo "All tests passed." diff --git a/test/functions.in b/test/functions.in new file mode 100644 index 0000000..8df4e3d --- /dev/null +++ b/test/functions.in @@ -0,0 +1,135 @@ +#!/bin/bash +srcdir=@SRCDIR@ +builddir=@BUILDDIR@ +tmpdir=$builddir/test-tmp +export NULLMAILER_TEST_PREFIX=$tmpdir +SYSCONFDIR=$tmpdir/conf +QUEUEDIR=$tmpdir/queue +rm -rf $tmpdir +mkdir -p \ + $tmpdir/protocols \ + $QUEUEDIR/{failed,queue,tmp} \ + $SYSCONFDIR +mknod $QUEUEDIR/trigger p +ln -s $builddir/src $tmpdir/sbin +ln -s $builddir/src $tmpdir/bin +ln -s $builddir/protocols/* $tmpdir/protocols/ + +exit_cleanup() { + svc -dx $tmpdir/service/* > /dev/null 2>&1 || : + # Remove all temporary files on success + if [ $? -eq 0 ] + then + wait + rm -rf $tmpdir + fi +} +trap exit_cleanup EXIT + +fail() { + echo "$*" + exit 1 +} +start() { + local name=$1 + shift + mkdir -p $tmpdir/service/$name + { + echo '#!/bin/sh' + echo exec "$@" + } >$tmpdir/service/$name/run + chmod +x $tmpdir/service/$name/run + supervise $tmpdir/service/$name </dev/null >$tmpdir/service/${name}-log 2>&1 & + sleep 1 +} +stop() { + for name in $*; do + svc -dx $tmpdir/service/$name >/dev/null 2>&1 + wait + done +} + +#not() { if "$@"; then return 1; else return 0; fi } +not() { ! safe "$@"; } +safe() { set +e; "$@"; result=$?; set -e; return $result; } +error() { + local code=$1 + shift + if "$@"; then + echo "Result was 0, should be $code." + return 1 + else + result=$? + if test $result -eq $code; then + return 0 + else + echo "Result was $result, should be $code." + return 1 + fi + fi +} + +inject() { ../src/nullmailer-inject "$@"; } +mailq() { ../src/mailq "$@"; } +smtpd() { ../src/nullmailer-smtpd "$@"; } +queue() { + ( + echo "$1" + shift + while [ x"$1" != x ] + do + echo "$1" + shift + done + echo + echo "Subject: test" + ) | ../src/nullmailer-queue > $tmpdir/queue-out 2> $tmpdir/queue-err +} +injectlines() { + for line in "$@"; do + echo "$line" + done | inject -n + return $? +} +injectfield() { + local field=$1 + shift + injectlines "$@" | grep -i "^$field:" | cut -d: -f2- +} +protocol() { + local p=$1 + local opts="" + shift + while [ $# -gt 0 -a x"$1" != x-- ] + do + opts="$opts $1" + shift + done + shift || : + for line in "$@" + do + echo "$line" + done > $tmpdir/protocol-in + ../protocols/$p $opts < $tmpdir/protocol-in > $tmpdir/protocol-log 2>&1 +} + +# Split an input on blank lines +splitblank() { + local fn=$1 + local n=1 + while read line + do + if [ x"$line" = x ] + then + n=$(( $n + 1 )) + else + echo "$line" >> ${fn}.$n + fi + done +} + +export PATH=/bin:/usr/bin:/usr/local/bin +rm -f $SYSCONFDIR/* +echo f.q.d.n >$SYSCONFDIR/me +echo q.d.n >$SYSCONFDIR/defaultdomain +set -e diff --git a/test/runtests b/test/runtests new file mode 100755 index 0000000..dcf9c31 --- /dev/null +++ b/test/runtests @@ -0,0 +1,17 @@ +#!/bin/sh +set -e + +failed=0 +for test in $* +do + echo Running test $test... + if env - bash $test + then + echo 'Done.' + else + echo '******************************Failed!******************************' + failed=$(( $failed + 1 )) + fi +done 2>&1 +echo "$# tests run, $failed failed" +exit $failed diff --git a/test/tests/dsn b/test/tests/dsn new file mode 100644 index 0000000..290d21d --- /dev/null +++ b/test/tests/dsn @@ -0,0 +1,108 @@ +. functions + +msgid=message.id.$$.$RANDOM@f.q.d.n +dsn() { + $builddir/src/nullmailer-dsn "$@" << EOF +sender@example.com +recip1@example.net +recip2@example.org + +Subject: test message +Message-Id: <$msgid> +From: <sender@example.com> +To: <recip1@example.net> +Cc: <recip2@example.org> + +This is a test. +line 2 +line 3 +line 4 +EOF +} + +fn=$tmpdir/dsn-tmp +dsn 5.2.9 | splitblank $fn + +echo -n Testing envelope: sender +not test -x $fn.1 +echo -n , recipient +grep -qx sender@example.com $fn.2 +echo -n , end +test $( wc -l < $fn.2 ) = 1 +echo + +date='..., [ 0-9][0-9] ... [0-9]{4} [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [+-][0-9]{4}' +echo -n Testing header: from +grep -qx 'From: Message Delivery Subsystem <MAILER-DAEMON@f.q.d.n>' $fn.3 +echo -n , to +grep -qx 'To: <sender@example.com>' $fn.3 +echo -n , subject +grep -qx 'Subject: Returned mail: Could not send message' $fn.3 +echo -n , date +egrep -q "^Date: $date$" $fn.3 +echo -n , message-id +grep -q '^Message-Id: <.*.nullmailer@f.q.d.n>$' $fn.3 +echo -n , mime +grep -qx 'MIME-Version: 1.0' $fn.3 +echo -n , content-type +grep -q '^Content-Type: multipart/report; report-type=delivery-status;' $fn.3 +echo + +echo -n Testing report header: reporting-mta +grep -qx "Reporting-MTA: x-local-hostname; f.q.d.n" $fn.8 +echo -n , date +egrep -q "^Arrival-Date: $date$" $fn.8 +echo + +echo -n Testing recipient report 1: final-recipient +grep -qx 'Final-Recipient: rfc822; recip1@example.net' $fn.9 +echo -n , action +grep -qx 'Action: failed' $fn.9 +echo -n , status +grep -qx 'Status: 5.2.9' $fn.9 +echo -n , date +egrep -q "^Last-Attempt-Date: $date$" $fn.9 +echo + +echo -n Testing recipient report 2: final-recipient +grep -qx 'Final-Recipient: rfc822; recip2@example.org' $fn.10 +echo -n , action +grep -qx 'Action: failed' $fn.10 +echo -n , status +grep -qx 'Status: 5.2.9' $fn.10 +echo -n , date +egrep -q "^Last-Attempt-Date: $date$" $fn.10 +echo + +echo Testing quoted message pre-header +grep -qx 'Content-Type: message/rfc822' $fn.11 + +echo Testing quoted message header +grep -qx "Message-Id: <$msgid>" $fn.12 + +echo Testing quoted message body +not grep -qx "This is a test." $fn.13 + +echo Testing fixed bounce address +echo admin@example.com > $SYSCONFDIR/bounceto +dsn 5.2.9 | splitblank $fn +grep -qx admin@example.com $fn.2 + +echo -n Testing max-lines: 0 +dsn --max-lines=0 5.2.9 | not grep -qx "This is a test." +echo -n , 1 +dsn --max-lines=1 5.2.9 | grep -qx "This is a test." +dsn --max-lines=1 5.2.9 | not grep -qx "line 2" +echo -n , 2 +dsn --max-lines=2 5.2.9 | grep -qx "line 2" +dsn --max-lines=2 5.2.9 | not grep -qx "line 3" +echo -n , bouncelines=1 +echo 1 > $SYSCONFDIR/bouncelines +dsn 5.2.9 | grep -qx "This is a test." +dsn 5.2.9 | not grep -qx "line 2" +echo -n , override +dsn --max-lines=2 5.2.9 | grep -qx "line 2" +dsn --max-lines=2 5.2.9 | not grep -qx "line 3" +echo + +rm -f $fn.* $SYSCONFDIR/bounceto $SYSCONFDIR/bouncelines diff --git a/test/tests/inject/bad-headers b/test/tests/inject/bad-headers new file mode 100644 index 0000000..a33dfeb --- /dev/null +++ b/test/tests/inject/bad-headers @@ -0,0 +1,15 @@ +. functions + +injtest() { echo "$@" | not inject >/dev/null; } + +echo "Checking that inject rejects leading continuation lines." +injtest " foo..." + +echo "Checking that inject rejects malformed RFC headers." +injtest "foo : bar" +injtest ":foo bar" +injtest "foo" + +echo "Checking that inject rejects bad addresses." +injtest "from: foo<bar" + diff --git a/test/tests/inject/date b/test/tests/inject/date new file mode 100644 index 0000000..9510436 --- /dev/null +++ b/test/tests/inject/date @@ -0,0 +1,12 @@ +. functions + +inj() { injectfield date 'to: nobody' "$@"; } + +echo "Checking that inject inserts a date line." +test -n "`inj`" + +echo "Checking that inject preserves an existing date line." +inj "date: foo" | grep '^ foo$' >/dev/null + +echo "Checking that inject does not add more date lines." +test 1 -eq `inj "date: foo" | wc -l` diff --git a/test/tests/inject/from b/test/tests/inject/from new file mode 100644 index 0000000..001b185 --- /dev/null +++ b/test/tests/inject/from @@ -0,0 +1,70 @@ +. functions + +inj() { injectfield from 'to: nobody' "$@"; } +testvar() { + set -e + echo "Checking that inject obeys $1." + export $1="$2" + inj | grep -q "$3" +} + +echo "Checking that inject inserts a from line." +test -n "`inj`" + +echo "Checking that inject preserves an existing from line." +inj "from: a@b.c" | grep -q '^ a@b\.c$' + +echo "Checking that inject does not add more from lines." +test 1 -eq `inj "from: a@b.c" | wc -l` + +echo "Checking that inject will strip from lines." +export NULLMAILER_FLAGS=f +inj "from: a@b.c" | not grep -q '^ a@b\.c$' +unset NULLMAILER_FLAGS + +echo "Checking that inject obeys me" +rm -f $SYSCONFDIR/default* +inj | grep -q "@f.q.d.n>$" + +echo "Checking that inject obeys config/defaulthost" +echo test.org >$SYSCONFDIR/defaulthost +inj | grep -q '@test.org>$' + +echo "Checking that inject obeys config/defaultdomain" +echo test >$SYSCONFDIR/defaulthost +echo domain.org >$SYSCONFDIR/defaultdomain +inj | grep -q '@test.domain.org>$' + +echo "Checking that inject ignores config/defaultdomain for localhost" +echo localhost >$SYSCONFDIR/defaulthost +inj | grep -q '@localhost>$' + +testvar HOSTNAME test1.org '@test1.org>$' + +testvar MAILHOST test2.org '@test2.org>$' + +testvar NULLMAILER_HOST test3.org '@test3.org>$' + +echo "Checking that inject uses getpwnam" +inj | grep -q " <`id -un`@" + +testvar LOGNAME name1 ' <name1@' + +testvar USER name2 ' <name2@' + +testvar MAILUSER name3 ' <name3@' + +testvar NULLMAILER_USER name4 ' <name4@' + +echo "Checking that inject uses a blank name." +inj | grep -q '^ <' + +testvar NAME full1 '^ full1 <' + +testvar MAILNAME full2 '^ full2 <' + +testvar NULLMAILER_NAME full3 '^ full3 <' + +echo "Checking that inject will use address-comment form." +export NULLMAILER_FLAGS=c +inj | grep -q '^ name4@test3.org (full3)$' diff --git a/test/tests/inject/from_ b/test/tests/inject/from_ new file mode 100644 index 0000000..33e973b --- /dev/null +++ b/test/tests/inject/from_ @@ -0,0 +1,10 @@ +. functions + +injectfrom() { injectlines "${1}From somebody" "Subject: test1" "To: nowhere"; } + +for lead in '' '>' +do + echo "Checking that inject ignores a leading \"${lead}From \" line" + injectfrom "$lead" | egrep -qv '^>?From ' + injectfrom "$lead" | head -n 1 | grep -q '^Subject:' +done diff --git a/test/tests/inject/message-id b/test/tests/inject/message-id new file mode 100644 index 0000000..a553a5d --- /dev/null +++ b/test/tests/inject/message-id @@ -0,0 +1,23 @@ +. functions + +inj() { injectfield message-id 'to: n' "$@"; } + +echo "Checking that inject inserts a message-id." +test -n "`inj`" + +echo "Checking that inject preserves an existing message-id." +inj "Message-Id: <mid@mid>" | grep -q '^ <mid@mid>$' + +echo "Checking that inject does not add more message-ids." +test 1 -eq `inj "Message-Id: <mid@mid>" | wc -l` + +echo "Checking that inject will ignore an existing message-id." +export NULLMAILER_FLAGS=i +inj "Message-Id: <mid@mid>" | not grep -q '^ <mid@mid>$' + +echo "Checking that inject obeys me" +inj | grep -q "@f.q.d.n>$" + +echo "Checking that inject obeys config/idhost" +echo test1.org >$SYSCONFDIR/idhost +inj | grep -q '@test1.org>$' diff --git a/test/tests/inject/queue b/test/tests/inject/queue new file mode 100644 index 0000000..fa2f8c2 --- /dev/null +++ b/test/tests/inject/queue @@ -0,0 +1,15 @@ +. functions + +echo 'Testing that inject queues messages properly.' + +echo 'To: nobody' | inject +test $( ls $QUEUEDIR/queue | wc -l ) = 1 +egrep -i '^to: *nobody' $QUEUEDIR/queue/* >/dev/null + +echo 'Testing that inject honors $NULLMAILER_QUEUE.' + +rm -f $QUEUEDIR/queue/* +export NULLMAILER_QUEUE=/bin/cat +echo 'To: nobody' | inject >/dev/null +test $( ls $QUEUEDIR/queue | wc -l ) = 0 +unset NULLMAILER_QUEUE diff --git a/test/tests/inject/recips b/test/tests/inject/recips new file mode 100644 index 0000000..008a2cb --- /dev/null +++ b/test/tests/inject/recips @@ -0,0 +1,50 @@ +. functions + +inj() { inject -n -v "$@" | tail -n +2 | sed '/^$/,$d'; } +inj-find() { echo to: a@b.c | inj "$1" d@e.f | grep -q "$2"; } +inj-notfind() { echo to: a@b.c | inj "$1" d@e.f | not grep -q "$2"; } + +hdrline='^a@b.c$' +cmdline='^d@e.f$' + +echo "Checking that inject uses command line with -a." +inj-find -a $cmdline + +echo "Checking that inject ignores header lines with -a." +inj-notfind -a $hdrline + +echo "Checking that inject uses command line with -b." +inj-find -b $cmdline + +echo "Checking that inject uses header lines with -b." +inj-find -b $hdrline + +echo "Checking that inject ignores command line with -h." +inj-notfind -h $cmdline + +echo "Checking that inject uses header lines with -h." +inj-find -h $hdrline + +echo "Checking that inject uses command line with -e and no header." +echo | inj -e d@e.f | grep -q $cmdline + +echo "Checking that inject uses command line with -e and header." +inj-find -e $cmdline + +echo "Checking that inject uses header with -e and no command line." +echo to: a@b.c | inj -e | grep -q $hdrline + +echo "Checking that inject ignores header with -e and command line." +inj-notfind -e $hdrline + +echo "Checking that inject uses command line with no header by default." +echo | inj -e d@e.f | grep -q $cmdline + +echo "Checking that inject uses command line with header by default." +inj-find -e $cmdline + +echo "Checking that inject uses header with no command line by default." +echo to: a@b.c | inj -e | grep -q $hdrline + +echo "Checking that inject ignores header with command line by default." +inj-notfind -e $hdrline diff --git a/test/tests/inject/return-path b/test/tests/inject/return-path new file mode 100644 index 0000000..a3f61d2 --- /dev/null +++ b/test/tests/inject/return-path @@ -0,0 +1,9 @@ +. functions + +inj() { injectfield return-path 'to: n' "$@"; } + +echo "Checking that inject does not inserts a return-path." +test -z "`inj`" + +echo "Checking that inject strips return-paths." +test -z "`inj return-path: blah`" diff --git a/test/tests/inject/sender b/test/tests/inject/sender new file mode 100644 index 0000000..77932a3 --- /dev/null +++ b/test/tests/inject/sender @@ -0,0 +1,86 @@ +. functions + +inj() { inject -n -v "$@" a </dev/null 2>/dev/null | head -n 1; } +testvar() { + set -e + echo "Checking that inject obeys $1." + export $1="$2" + inj | grep -q "$3" +} +testcanon() { + set -e + echo "Checking that inject canonicalizes $1." + export $1="$2" + inj | grep -q "$3" +} +testhdr() { + set -e + echo "Checking that inject $1 $2:" + echo $2: $3 | inject -n -v a 2>/dev/null | head -n 1 | grep -q "$4" +} +testign() { testhdr ignores "$@"; } +testset() { testhdr uses "$@"; } +testfrom() { + echo "Checking that inject honors -f '$1'" + inj -f "$1" | grep -qx "$2" +} +testfrom2() { + testfrom "$1" "$2" + testfrom "<$1>" "$2" +} + +echo "Checking that inject obeys me" +rm -f $SYSCONFDIR/default* +inj | grep -q "@f.q.d.n$" + +echo "Checking that inject obeys config/defaulthost" +echo test.org >$SYSCONFDIR/defaulthost +inj | grep -q '@test.org$' + +echo "Checking that inject obeys config/defaultdomain" +echo test >$SYSCONFDIR/defaulthost +echo domain.org >$SYSCONFDIR/defaultdomain +inj | grep -q '@test.domain.org$' + +echo "Checking that inject ignores config/defaultdomain for localhost" +echo localhost >$SYSCONFDIR/defaulthost +inj | grep -q '@localhost$' + +testvar HOSTNAME test1.org '@test1.org$' + +testcanon HOSTNAME test1 '@test1.domain.org$' + +testvar MAILHOST test2.org '@test2.org$' + +testcanon MAILHOST test2 '@test2.domain.org$' + +testvar NULLMAILER_HOST test3.org '@test3.org$' + +testcanon NULLMAILER_HOST test3 '@test3.domain.org$' + +echo "Checking that inject uses getpwnam" +inj | grep -q "^`id -un`@" + +testvar LOGNAME name1 '^name1@' + +testvar USER name2 '^name2@' + +testvar MAILUSER name3 '^name3@' + +testvar NULLMAILER_USER name4 '^name4@' + +testign Errors-To a@b.c '^name4@test3' +testign From a@b.c '^name4@test3' +testign Reply-To a@b.c '^name4@test3' +testign Resent-From a@b.c '^name4@test3' +testign Resent-Reply-To a@b.c '^name4@test3' +testign Resent-Sender a@b.c '^name4@test3' +testign Return-Receipt-To a@b.c '^name4@test3' +testign Sender a@b.c '^name4@test3' +testset Return-Path name0@host0.org '^name0@host0.org$' +export NULLMAILER_FLAGS=s +testign Return-Path name0@host0.org '^name4@test3' + +testfrom2 '' '' +testfrom2 'a@b.c' 'a@b.c' +testfrom2 'a@b' 'a@b.domain.org' diff --git a/test/tests/mailq b/test/tests/mailq new file mode 100644 index 0000000..0c50ba6 --- /dev/null +++ b/test/tests/mailq @@ -0,0 +1,10 @@ +. functions + +echo "Testing the output of the mailq command" +echo To: nobody@nowhere | inject + +$builddir/src/mailq | head -n 1 | egrep -q '^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]+ bytes from <.*>$' \ +|| { echo "Header is misformatted."; exit 1; } + +$builddir/src/mailq | tail -n 1 | egrep -q '^ to <nobody@nowhere.q.d.n>$' \ +|| { echo "Recipient is misformatted."; exit 1; } diff --git a/test/tests/protocols b/test/tests/protocols new file mode 100644 index 0000000..8f79737 --- /dev/null +++ b/test/tests/protocols @@ -0,0 +1,69 @@ +. functions +export HELOHOST=f.q.d.n + +rm -f testmail +cat >testmail <<EOF +bruce@untroubled.org +bruce@untroubled.org + +From: <bruce@untroubled.org> +To: <bruce@untroubled.org> +Subject: Nullmailer automated test message + +Just testing, please ignore +EOF + +for p in smtp qmqp +do + start server "tcpserver -1 ::0 0 sh $srcdir/test/accept-$p.sh" + port=$( head -n 1 $tmpdir/service/server-log ) + + echo "Testing protocol success with $p (command-line)" + protocol $p --host=localhost --port=$port 3<testmail + + echo "Testing protocol success with $p (stdin)" + protocol $p -- host=localhost port=$port 3<testmail + + echo "Testing protocol success with $p (stdin, IPv6)" + protocol $p -- host=::1 port=$port 3<testmail + + echo "Testing protocol success with $p (source addr)" + protocol $p -- host=::1 port=$port source=::1 3<testmail + + echo "Testing protocol failure with $p (bad source addr 1)" + error 19 protocol $p -- host=::1 port=$port source=127.0.0.1 3<testmail + + echo "Testing protocol failure with $p (bad source addr 2)" + error 19 protocol $p -- host=127.0.0.1 port=$port source=::1 3<testmail + + stop server + + echo "Testing host not found error with $p." + error 2 protocol $p --host=this.host.can.not.exist 3<testmail + + echo "Testing connection refused error with $p." + error 7 protocol $p -p $port --host=localhost 3<testmail + + echo "Testing connection refused error with $p (IPv6)." + error 7 protocol $p -p $port --host=::1 3<testmail + + echo "Testing usage error with $p (zero args)." + error 1 protocol $p 3<testmail + + echo "Testing usage error with $p (two args)." + error 1 protocol $p --host=localhost foobar 3<testmail + + echo "Testing usage error with $p (unknown option)." + error 1 protocol $p -x --host=localhost 3<testmail + + echo "Testing usage error with $p (invalid integer)." + error 1 protocol $p -p foo --host=localhost 3<testmail + + start server tcpserver -1 0 0 date + port=$( head -n 1 $tmpdir/service/server-log ) + echo "Testing protocol failure with $p." + error 11 protocol $p -p $port --host=localhost 3<testmail + stop server +done + +rm -f testmail diff --git a/test/tests/queue/rewrite b/test/tests/queue/rewrite new file mode 100644 index 0000000..780aa3b --- /dev/null +++ b/test/tests/queue/rewrite @@ -0,0 +1,82 @@ +. functions + +que() { + set -e + ../src/nullmailer-queue && \ + cat $QUEUEDIR/queue/* && \ + rm -f $QUEUEDIR/queue/* +} +que-recip() { + set -e + que | sed -e '2,/^$/!d' | grep -q "$@" +} +que-sender() { + set -e + que | head -n 1 | grep -q "$@" +} + +echo admin@remote >$SYSCONFDIR/adminaddr + +echo "Checking that queue rewrites user@localhost to adminaddr." +que-recip '^admin@remote$' <<EOF +bruceg@qcc.sk.ca +user@localhost + +header + +data +EOF + +echo "Checking that queue rewrites user@hostname to adminaddr." +que-recip '^admin@remote$' <<EOF +bruceg@qcc.sk.ca +user@f.q.d.n + +header + +data +EOF + +echo "Checking that queue does not rewrite non-local users." +que-recip '^user@nowhere.org$' <<EOF +bruceg@qcc.sk.ca +user@nowhere.org + +header + +data +EOF + +echo admin1@remote1,admin2@remote2 >$SYSCONFDIR/adminaddr + +echo "Checking that queue rewrites to multiple adminaddr." +que-recip '^admin2@remote2$' <<EOF +bruceg@qcc.sk.ca +user@localhost + +header + +data +EOF + +echo "Checking that queue transmits the envelope sender normally." +que-sender '^bruceg@qcc.sk.ca$' <<EOF +bruceg@qcc.sk.ca +user@localhost + +header + +data +EOF + +echo "Checking that queue rewrites sender with allmailfrom." +echo sender@remote3 >$SYSCONFDIR/allmailfrom +que-sender '^sender@remote3$' <<EOF +bruceg@qcc.sk.ca +user@localhost + +header + +data +EOF +rm -f $SYSCONFDIR/allmailfrom diff --git a/test/tests/queue/validate b/test/tests/queue/validate new file mode 100755 index 0000000..0ea71cd --- /dev/null +++ b/test/tests/queue/validate @@ -0,0 +1,56 @@ +#!/bin/bash +. functions + +queuedir=$QUEUEDIR/queue +queue-test() { + rm -f $queuedir/* + echo "Testing queue from <$1> to <$2>" + queue "$@" +} + +queue-good() { + if ! queue-test "$@" + then + fail "nullmailer-queue failed to accept good envelope" + fi + qc=$( find $queuedir -type f | wc -l ) + if [ $qc -eq 0 ] + then + fail "nullmailer-queue did not queue a message despite succeeding" + fi + if [ $qc -gt 1 ] + then + fail "nullmailer-queue queued multiple messages ?!?" + fi + qm=$queuedir/* + sed -e '1,/^$/d' $qm | grep -q '^Subject:' || fail "queued message did not contain body" +} + +check-sender() { + qm=$queuedir/* + head -n 1 $qm | grep -q "^$1$" || fail "queued message contained wrong sender" +} + +check-recipient() { + qm=$queuedir/* + sed -e '1d;q' $qm | grep -q "^$1$" || fail "queued message contained wrong sender" +} + +queue-bad() { + if queue-test "$@" + then + fail "nullmailer-queue failed to reject bad envelope" + fi + qc=$( find $queuedir -type f | wc -l ) + if [ $qc -ne 0 ] + then + fail "nullmailer-queue queued a message after rejecting it" + fi +} + +queue-good "a@b.c" "d@e.f" +queue-bad "@b.c" "d@e.f" +queue-bad "a@b.c" "@e.f" +queue-bad "a@b" "d@e.f" +queue-bad "a@b.c" "d@e" +queue-good "" "d@e.f" diff --git a/test/tests/send b/test/tests/send new file mode 100644 index 0000000..5444410 --- /dev/null +++ b/test/tests/send @@ -0,0 +1,83 @@ +. functions + +cat <<EOF >$tmpdir/protocols/dummy +#!/bin/sh +set -e +read opts +read code +echo "\$opts" | grep -q '^host=' +echo "code=\$code (#5.2.1) \$opts" +exit \$code +EOF +chmod +x $tmpdir/protocols/dummy + +echo 127.0.0.1 smtp >$SYSCONFDIR/remotes + +# Start up the servers +start send $builddir/src/nullmailer-send + +make_message() { + msgid=$(date +%s).$$.me + cat <<EOF >$QUEUEDIR/tmp/$msgid +me@example.com +me@example.net + +Subject: test +Message-Id: <$msgid> + +This is just a test. +EOF + mv -f $QUEUEDIR/tmp/$msgid $QUEUEDIR/queue/$msgid +} + +send_message() { + echo 127.0.0.1 dummy $@ >$SYSCONFDIR/remotes + make_message + svc -a $tmpdir/service/send + sleep 2 + not test -e $QUEUEDIR/queue/$msgid +} + +echo 'Testing sending with a succeeding protocol' +send_message 0 2.0.0 + +echo 'Testing sending with a failing protocol' +not send_message 1 5.2.2 +rm -f $QUEUEDIR/queue/$msgid + +echo 'Testing handling of a permanent failure' +send_message 33 5.2.2 + +echo 'Checking failed message was moved out of the queue' +test -e $QUEUEDIR/failed/$msgid +rm -f $QUEUEDIR/failed/$msgid + +echo 'Checking for a generated bounce message' +# It will also bounce, so look at failed messages +msgid2=$( ls $QUEUEDIR/failed ) +test $( wc -w <<< $msgid2 ) = 1 +fn=$QUEUEDIR/failed/$msgid2 + +echo 'Checking bounce sender' +head -n 1 $fn | grep -qx '' + +echo 'Checking bounce recipient' +sed -e '1d;q' $fn | grep -qx 'me@example.com' +sed -e '1,2d;q' $fn | grep -qx '' + +echo 'Checking bounce contents' +sed -e '1,3d; /^$/q' $fn | grep -qx 'To: <me@example.com>' +sed -e '1,3d; 1,/^$/d' $fn | grep -qx 'Reporting-MTA: x-local-hostname; f.q.d.n' +sed -e '1,3d; 1,/^$/d' $fn | grep -qx 'Final-Recipient: rfc822; me@example.net' +sed -e '1,3d; 1,/^$/d' $fn | grep -qx 'Action: failed' +sed -e '1,3d; 1,/^$/d' $fn | grep -qx 'Status: 5.2.1' +sed -e '1,3d; 1,/^$/d' $fn | grep -qx 'Diagnostic-Code: DUMMY; code=33 (#5.2.1) host=127.0.0.1' +sed -e '1,3d; 1,/^$/d' $fn | grep -qx 'Subject: test' +sed -e '1,3d; 1,/^$/d' $fn | not grep -qx 'This is just a test.' + +echo 'Checking log outputs' +log=$tmpdir/service/send-log +grep -qx "^Starting delivery: host: 127.0.0.1 protocol: dummy file: $msgid" $log +grep -qx 'From: <me@example.com> to: <me@example.net>' $log +grep -qx 'Sending failed: Unspecified temporary error' $log +grep -qx "Message-Id: <$msgid>" $log diff --git a/test/tests/smtpd b/test/tests/smtpd new file mode 100644 index 0000000..ff326e1 --- /dev/null +++ b/test/tests/smtpd @@ -0,0 +1,84 @@ +. functions + +echo "Testing the nullmailer-smtpd program" + +out=$tmpdir/smtpd.out.$$ + +smtpd <<EOF 2>&1 | cat -v >$out +HELO +HELO somebody +EHLO +EHLO somebody +HELP +HELP something +DATA +RCPT +RCPT TO:<r@example.com> +MAIL +MAIL FROM:<f@example.com> +RCPT +RCPT TO:<r@example.com> +RSET +RCPT TO:<r@example.com> +MAIL FROM:<> +RSET +MAIL FROM:<f0@example.com> +RCPT TO:<r0@example.com> +mail from f@example.com +rcpt to r@example.com +rcpt <@example.org:r2@example.com> +DATA +Subject: test + +testing SMTP +.line 2 +..line 3 +. +QUIT +QUIT +EOF + +diff -u - $out <<EOF +220 nullmailer-smtpd ready^M +501 5.5.2 Syntax error, command requires a parameter^M +250 2.3.0 OK^M +501 5.5.2 Syntax error, command requires a parameter^M +250 2.3.0 OK^M +214 2.0.0 Help not available^M +214 2.0.0 Help not available^M +503 5.5.1 You must send a valid sender first^M +501 5.5.2 Syntax error, command requires a parameter^M +503 5.5.1 You must send a valid sender first^M +501 5.5.2 Syntax error, command requires a parameter^M +250 2.1.0 Sender accepted^M +501 5.5.2 Syntax error, command requires a parameter^M +250 2.1.5 Recipient accepted^M +250 2.3.0 OK^M +503 5.5.1 You must send a valid sender first^M +250 2.1.0 Sender accepted^M +250 2.3.0 OK^M +250 2.1.0 Sender accepted^M +250 2.1.5 Recipient accepted^M +250 2.1.0 Sender accepted^M +250 2.1.5 Recipient accepted^M +250 2.1.5 Recipient accepted^M +354 End your message with a period on a line by itself^M +250 2.6.0 Accepted message^M +221 2.0.0 Good bye^M +EOF + +echo ' testing queued message envelope' +qf=$QUEUEDIR/queue/* +grep -q '^f@example.com$' $qf +grep -q '^r@example.com$' $qf +grep -q '^r2@example.com$' $qf +not grep -q '^f0@example.com$' $qf +not grep -q '^r0@example.com$' $qf +echo ' testing queued message contents' +grep -q '^Subject: test$' $qf +grep -q '^Received: ' $qf +grep -q '^testing SMTP$' $qf +grep -q '^line 2$' $qf +grep -q '^\.line 3$' $qf +test $( wc -l < $qf ) = 11 +test $( wc -w < $qf ) = 25 |