فهرست منبع

* Eggdrop 1.6.12

Eggheads Development Team 24 سال پیش
والد
کامیت
fcfd3bd0dc
100فایلهای تغییر یافته به همراه21345 افزوده شده و 6935 حذف شده
  1. 0 51
      CONTENTS
  2. 0 339
      COPYING
  3. 0 192
      FEATURES
  4. 0 121
      INSTALL
  5. 170 84
      Makefile.in
  6. 586 0
      README
  7. 15 2
      acconfig.h
  8. 391 204
      aclocal.m4
  9. 159 99
      config.h.in
  10. 576 202
      configure
  11. 35 21
      configure.in
  12. 0 3
      lush.h.in
  13. 1308 0
      misc/config.guess
  14. 1413 0
      misc/config.sub
  15. 1 1
      misc/install-sh
  16. 1 1
      misc/mkinstalldirs
  17. 741 0
      misc/modconfig
  18. 156 74
      src/Makefile.in
  19. 258 0
      src/bg.c
  20. 36 0
      src/bg.h
  21. 193 174
      src/botcmd.c
  22. 66 79
      src/botmsg.c
  23. 393 196
      src/botnet.c
  24. 126 106
      src/chan.h
  25. 238 211
      src/chanprog.c
  26. 247 245
      src/cmds.c
  27. 9 9
      src/cmdt.h
  28. 92 0
      src/compat/Makefile.in
  29. 35 0
      src/compat/compat.h
  30. 1257 0
      src/compat/gnu_strftime.c
  31. 186 0
      src/compat/inet_aton.c
  32. 40 0
      src/compat/inet_aton.h
  33. 35 0
      src/compat/memcpy.c
  34. 38 0
      src/compat/memcpy.h
  35. 35 0
      src/compat/memset.c
  36. 42 0
      src/compat/memset.h
  37. 721 0
      src/compat/snprintf.c
  38. 53 0
      src/compat/snprintf.h
  39. 50 0
      src/compat/strcasecmp.c
  40. 46 0
      src/compat/strcasecmp.h
  41. 35 0
      src/compat/strftime.c
  42. 42 0
      src/compat/strftime.h
  43. 263 229
      src/dcc.c
  44. 161 126
      src/dccutil.c
  45. 539 0
      src/dns.c
  46. 52 0
      src/dns.h
  47. 374 244
      src/eggdrop.h
  48. 84 77
      src/flags.c
  49. 144 123
      src/flags.h
  50. 404 489
      src/lang.h
  51. 125 132
      src/language.c
  52. 336 256
      src/main.c
  53. 42 38
      src/main.h
  54. 3 3
      src/match.c
  55. 20 5
      src/md5/Makefile.in
  56. 0 40
      src/md5/global.h
  57. 19 39
      src/md5/md5.h
  58. 242 324
      src/md5/md5c.c
  59. 74 74
      src/mem.c
  60. 354 293
      src/misc.c
  61. 97 0
      src/misc_file.c
  62. 31 0
      src/misc_file.h
  63. 136 44
      src/mod/Makefile.in
  64. 25 15
      src/mod/blowfish.mod/Makefile
  65. 22 5
      src/mod/blowfish.mod/bf_tab.h
  66. 97 71
      src/mod/blowfish.mod/blowfish.c
  67. 31 40
      src/mod/blowfish.mod/blowfish.h
  68. 0 24
      src/mod/buildstatic
  69. 27 15
      src/mod/channels.mod/Makefile
  70. 335 195
      src/mod/channels.mod/channels.c
  71. 70 21
      src/mod/channels.mod/channels.h
  72. 264 297
      src/mod/channels.mod/cmdschan.c
  73. 369 185
      src/mod/channels.mod/tclchan.c
  74. 149 0
      src/mod/channels.mod/udefchan.c
  75. 323 283
      src/mod/channels.mod/userchan.c
  76. 49 0
      src/mod/compress.mod/Makefile.in
  77. 444 0
      src/mod/compress.mod/compress.c
  78. 52 0
      src/mod/compress.mod/compress.h
  79. 7 0
      src/mod/compress.mod/compress_config.h.in
  80. 1049 0
      src/mod/compress.mod/configure
  81. 48 0
      src/mod/compress.mod/configure.in
  82. 117 0
      src/mod/compress.mod/tclcompress.c
  83. 25 14
      src/mod/console.mod/Makefile
  84. 61 63
      src/mod/console.mod/console.c
  85. 38 0
      src/mod/console.mod/console.h
  86. 25 15
      src/mod/ctcp.mod/Makefile
  87. 91 88
      src/mod/ctcp.mod/ctcp.c
  88. 9 9
      src/mod/ctcp.mod/ctcp.h
  89. 49 0
      src/mod/dns.mod/Makefile.in
  90. 1115 0
      src/mod/dns.mod/configure
  91. 102 0
      src/mod/dns.mod/configure.in
  92. 1129 0
      src/mod/dns.mod/coredns.c
  93. 226 0
      src/mod/dns.mod/dns.c
  94. 81 0
      src/mod/dns.mod/dns.h
  95. 36 0
      src/mod/eggautoconf
  96. 46 0
      src/mod/eggmod.m4
  97. 532 0
      src/mod/eggmod.sh
  98. 28 16
      src/mod/irc.mod/Makefile
  99. 477 328
      src/mod/irc.mod/chan.c
  100. 472 301
      src/mod/irc.mod/cmdsirc.c

+ 0 - 51
CONTENTS

@@ -1,51 +0,0 @@
-One (1) eggdrop bot (n.)  Functional on many UNIX platforms. README is
-   included for you (human) to read (please). Helpful stuff.
-
-"What are all these files for?"
-
-COPYING
-   legal stuff
-
-FEATURES
-   just tells you what eggdrop can do -- a kind of advertisement
-
-Makefile
-Makefile.in
-   help with automated making of bot
-
-NEWS
-   lists significant differences with previous versions, if you're used
-   to using a previous version, or upgrading READ IT.
-
-README
-   what you should read before trying to compile eggdrop -- contains
-   tips on compiling, and an explanation of what eggdrop does
-
-config*
-   scripts/files for automatic configure of the bot
-
-doc/
-   lots of IMPORTANT DOCUMENTATION that you must read!
-
-eggdrop.conf.dist
-   sample configuration for your bot
-
-filesys/
-   sample filesystem
-
-help/
-   the online help files for the bot
-
-language/
-   a directory of language files, for multiple language support.
-   More information on contributing/customising for languages will be
-   forthcoming.
-
-motd
-   sample "message of the day" displayed to party-line users as they join
-
-scripts/
-   some tcl scripts that you might want to use
-
-src/
-   the eggdrop source

+ 0 - 339
COPYING

@@ -1,339 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                          675 Mass Ave, Cambridge, MA 02139, 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
-
-	Appendix: 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) 19yy  <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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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.

+ 0 - 192
FEATURES

@@ -1,192 +0,0 @@
-EGGDROP -- AN IRC BOT
-
-Eggdrop is the most advanced IRC robot available.  It has been under
-development since December 1993, and, unlike most other bots, it is
-still regularly updated.  Its features include:
-
-  * completely different channel user lists like having a seperate bot for
-    each channel.
-
-  * complete channel protection, customizable via config file: permanently
-    store a ban list with comments, etc
-
-  * user records saved on disk and alterable via dcc chat: each user can
-    have a password (encrypted), a list of valid hostmasks, a set of access
-    flags, etc
-
-  * the ability to "learn" new users (if you choose to have the bot do so)
-    by letting users /MSG the bot "hello" and granting them automatic access
-    of whatever type you specify (or even no access at all)
-
-  * a "party line" available through dcc chat or telnet, with multiple
-    channels, giving you the ability to talk to people without being affected
-    by netsplits
-
-  * console mode: you can view each channel through dcc chat or telnet,
-    selectively looking at mode changes, joins and parts, channel talk, or
-    any combination of the above
-
-  * a file system where people can upload and download files, in an
-    environment that looks and acts (for the most part) like a typical
-    unix system -- plus the ability to mark directories as hidden/
-    unaccessable to people without certain user flags
-
-  * bot network: link two or more bots together for a party line that can
-    stretch not only across channels, but across irc networks (one bot on
-    EFnet, one bot on Undernet, etc)
-
-  * script language: commands and features can be added to the bot on the
-    fly, by means of the TCL script language, giving you the power of TOTAL
-    customization of your bot -- similar to ircII script
-
-!!!  WARNING  !!!
-
-Eggdrop is NOT a simple bot to use.  It is an advanced bot for people who
-know IRC and know what they're doing.  If you don't know what DCC CHAT is
-or how to use it -- if you don't know the difference between #channels and
-&channels -- if you don't know what a clonebot or CTCP avalanche is -- then
-this bot is not for you.  Choose a simpler bot like Vladbot or Baloobot or
-ComBot, or find one of the many scriptbots to use.
-
-  This is the 1.4.xx branch of the Eggdrop Bot.
-
-*** NOTE:
-
-    This bot is NOT intended for users of very limited MEMORY or DISK
-    shell accounts.  The development of this latest design of Eggdrop
-    is geared towards features and flexibility.  If you have restraints
-    on the resources allowed to run your bot, then you should instead
-    consider the 1.0 Eggdrop version.
-
-***
-
-This latest development of Eggdrop is now compilable in either of two
-configurations:
-
-MODULE - dynamic
-
-   The MODULE version of Eggdrop 1.4.xx provides for the on-the-fly
-   loading of extensions to the bot code without having to recompile
-   the entire bot.  This is available on OS platforms which support
-   dynamically linked/shared libraries in their run-time and TCL
-   libraries.  It allows for functionality of the bot to be loaded
-   and unloaded at any time.
-
-   The base loadable modules distributed with this Eggdrop version
-   are:
-        assoc           This is the functionality of the `assoc'
-                        command for naming party `chat' lines.  It
-                        also serves as an example for writing your
-                        own modules.
-        blowfish        The standard Eggdrop encrypting routines
-                        for passwords and other encrytions.  This
-                        can be replaced with a user-written module
-                        to perform their own encrypting algorithms.
-        channels        This allows eggdrop to have channel info stored
-                        and used on that server that you allowed for with
-                        the server module.
-        console         This provides storage of console settings when you
-                        exit the bot (or .store).
-        ctcp            This provides the normal ctcp replies that you'd
-                        expect.
-        filesys         This module performs the file-system
-                        operation for DCC file transfers to and from
-                        the BOT over via IRC DCC commands.
-        irc             This controls all other irc related stuff. Not
-                        loading it is the equivalent of the old NO_IRC
-                        setting.
-        notes           This provides support for storing of notes for
-                        users from each other. Notes between currently
-                        online users is supported in the core, this is
-                        only for storing the notes for later retrieval,
-                        direct user->user notes are built-in.
-        seen            This provides seen commands via msg, on channel or
-                        via dcc, similar to the various scripts.
-        server          This allows eggdrop to connect to a server, but
-                        that's about it.
-        share           This provides the userfile sharing support (this
-                        requires the channels & transfer modules).
-        transfer        This module performs the bot-to-bot userfile
-                        sharing necessary for sharebots.  It is
-                        loaded automatically when filesys is loaded.
-        wire            This provides an encrypted partyline
-                        communication.
-        woobie          This is a example/skeletal module for writing
-                        your own module.
-
-MODULE - static
-
-   The STATIC-MODULE version of Eggdrop 1.4.xx is pretty much the same
-   as the module bot, except each individual module is linked into the
-   excutable. You still need to 'loadmodule <module>' to turn them on.
-
-See the file doc/MODULES for more specific MODULE information.
-New to 1.4.xx (applies to 1.3.xx also):
-
-**** BOTNET
-
-Major protocol changes, lots less messages & bytes used.
-
-You WILL get double messages if you link OLD<->NEW<->NEW<->OLD
-(or any number of NEW's between them).
-To prevent this, have all your new bots on 1 side of the botnet, and
-all the old ones  on the other (although OLD<->NEW<->OLD should be ok).
-
-The order of the version and handshake messages has reversed this means
-on a new botlink between an OLD & a NEW, but you must .link from the OLD
-or the NEW wont know the password.
-
-**** USERLIST
-
-If you want to have the option of going back to an old version SAVE your
-userlist!!  This is a new version userlist, and it's not backwards
-compatible once written (it can still READ old userlists take note).
-
-**** FLAGS
-
-Flags have multiplied & split up: normal user/channel flags still exist
-and are setable by .chattr.  You can also now use .chattr +o|-o #channel.
-New are the "user-defined" flags which are all of A-Z for users & channels.
-Also, bot attributes are seperated now and are set using .botattr.
-Bots have "user-defined" flags 0-9.
-The old 0-9 user defined flags will be converted to A-J when you upgrade your
-userfile.
-
-**** SHARING
-
-*BIG CHANGE* well, big in use, small in code ;)
-
-There are now 2 sharing flags, +p = passive share, +s = aggressive share.
-Your bot will only accept sharing with passively with 1 bot at a time,
-although any number of aggressive shares is fine.
-
-Consider the botnet:
-
-HubBotA
-  |-+LeafBotA
-  `-+HubBotB
-       |-+LeafBotB
-  `-or `-+LeafBotC
-
-Flags would be set as such:
-
-HubBotA has:
-   LeafBotA: +sl
-   HubBotB : +s
-   LeafBotC: +sl
-LeafBotA has:
-   HubBotA : +ph
-HubBotB  has:
-   LeafBotB: +sl
-   LeafBotC: +sl
-LeafBotB has:
-   HubBotB : +ph
-LeafBotC has:
-   HubBotB : +ph
-   HubBotA : +ph
-
-how's that look? :)
-
-**** Installation
-
-  make install DEST=<directory>

+ 0 - 121
INSTALL

@@ -1,121 +0,0 @@
-                       _
-  ___   __ _  __ _  __| |_ __  ___  _ __
- / _ \ / _` |/ _` |/ _` | '__|/ _ \| '_ \
-|  __/| (_| | (_| | (_| | |  | (_) | |_) |
- \___| \__, |\__, |\__,_|_|   \___/| .__/
-       |___/ |___/                 |_|     v1.4
-
-This is the quick install guide, if you have had little or no
-experience with unix or eggdrop, READ THE README FILE NOW!
-This file is only for experienced users.
-
-(1) WHAT IS EGGDROP?
-
-    Please, read the file README before attempting to set up this bot. It
-    is NOT easy to use! This file is a quick setup guide, not a miracle
-    worker. If you enter this file without basic eggdrop knowledge, you
-    will NOT leave with a working bot! Before asking ANY questions, READ
-    THE README FILE OR YOU WILL BE BURNED TO A HORRIBLE DEATH! IF YOU DO
-    NOT READ THAT FILE I WILL PERSONALLY WALK TO YOUR TERMINAL AND BEAT IT
-    WITH A SMELLY SNEAKER! By the way, read README.
-
-(2) QUICK STARTUP
-
-    Eggdrop uses the GNU autoconfigure scripts, to make things easier.
-
-    1. Type './configure' from the eggdrop directory.  That script will
-       determine how your system is set up, and figure out how to compile
-       eggdrop.  It will also try to find Tcl, which is required to
-       compile.
-
-    2. Type 'make' from the eggdrop directory.  Or to force a statically
-       linked module bot type 'make static'.  Otherwise the Makefile will
-       determin which type of bot your system will support.  Dynamic is
-       always the better way to go if possible. There're also the options
-       debug and sdebug (static-debug) which will give more detailed
-       output on (a highly unlikely :) crash. This might help the devteam
-       to track down the crash and fix the bug. Debug and sdebug will take
-       a little longer to compile and will enlarge the binary a bit, but
-       it's worth if you want to support eggdrop development.
-
-    3. Eggdrop must be installed in a directory somewhere.  This is
-       accomplished by entering the unix command:
-		make install DEST=<directory>
- 		example make install DEST=/home/egguser/eggdrop
-        (note you must use full path for every file to be correctly installed)
-
-	[The following is performed from the directory installed above]
-
-    4. Copy the file 'eggdrop.conf.dist' to a new file, usually the
-       same name as the bot that will use it, e.g. "LamestBot".
-
-    5. Edit your config file LamestBot completely.
-
-    6. Start the bot with the "-m" option to create a user file, ie
-       'eggdrop -m LamestBot'.
-
-    7. When starting the bot in the future, drop the "-m".  If you have
-       edited your bot script correctly, you can type:
-           chmod u+x <my-bot-script-name>
-       e.g.
-           chmod u+x LamestBot
-       and from then on, you will be able to run your bot directly from the
-       script.  So you can just type "LamestBot" from your shell prompt to
-       start up your bot.  For this to work, the top line of your script MUST
-       contain the correct path to eggdrop.
-
-    8. It's advisable to run your bot via crontab so that it will automatic-
-       ally restart if the machine goes down or (heaven forbid) the bot
-       should crash. Look at the file 'scripts/botchk' and 'scripts/autobotchk'
-       for a great start with crontabbing the bot.
-
-    9. Smile, and if you haven't already read the README file in its
-       entirety, go take a long walk off a short pier.
-
-
-(3) MODULES
-
-  1.  Modules are small pieces of code that can either be compiled into
-the binary or can be compiled seperatly in a file.  This allows for a much
-smaller binary and a way of choosing which options you want installed in
-the bot.  Before you compile the bot you can remove any *.mod directory in
-the src/mod that you dont wish to be compiled.  Use caution though most of
-the modules that come with eggdrop the are required.  The exception is
-woobie.mod and seen.mod.  If you do not want these modules it is safe
-to delete those directories.
-
-  2.  If there are any personal modules that you have made or downloaded
-you can add them to the bot by placing them in the /src/mod directory with
-a mod extension.  They will be automatically compiled during the make for
-you.  They must have a valid make file and of course be compatiable with
-the rest of the eggdrop source.
-
-  3.  If you wish to add a module at a latter time follow the same steps
-in paragraph 2.  After you have moved the appropriate files you will only
-need to type make modules to compile only the modules portion of the bot.
-
-
-(3) FREQUENTLY ASKED QUESTIONS
-
-    1. WHAT DO I DO IF...?
-
-       READ THE README FILE!
-
-    2. THE README DOES NOT ANSWER...!
-
-       READ THE README FILE AGAIN!
-
-
-    3. I still don't know how to....
-
-       Well, go to www.egghelp.org or www.eggheads.org and see if you can
-       find there what you're looking for. There're also lots of IRC help
-       channels (usually #eggdrop) and various mailinglists. Try Eggheads
-       mailinglist http://scrambled.eggheads.org/mailman/listinfo/eggheads
-
-
-This is the end. If you read to this point, hopefully you have also read
-the README file. If not, then READ IT!&@#%@!
-
-Have fun with Eggdrop!
-

+ 170 - 84
Makefile.in

@@ -1,11 +1,13 @@
 #
-#  This is the Makefile for EGGDROP (the irc bot)
+#  This is the Makefile for EGGDROP (the IRC bot)
 #  You should never need to edit this.
 #
-# $Id: Makefile.in,v 1.31 1999/12/15 02:32:56 guppy Exp $
+# $Id: Makefile.in,v 1.30 2002/02/28 05:13:54 wcc Exp $
 
-SHELL = /bin/sh
+SHELL = @SHELL@
 top_srcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
 
 @SET_MAKE@
 prefix = @prefix@
@@ -42,6 +44,7 @@ MOD_STRIP = @MOD_STRIP@
 SHLIB_CC = @SHLIB_CC@
 SHLIB_LD = @SHLIB_LD@
 SHLIB_STRIP = @SHLIB_STRIP@
+MOD_EXT = @MOD_EXT@
 
 # programs make install uses
 LN_S = @LN_S@
@@ -61,57 +64,78 @@ XLIBS = @TCL_LIBS@ @LIBS@
 TCLLIB = @TCLLIB@
 TCLLIBFN = @TCLLIBFN@
 
-CFLAGS = @CFLAGS@ -I.. @DEFS@ $(CFLGS)
-DEBCFLAGS = @CFLAGS@ -I.. @DEFS@ -DDEBUG_ASSERT -DDEBUG_MEM $(CFLGS)
+DEBCFLAGS = -DDEBUG_ASSERT -DDEBUG_MEM 
+
+modconf = $(top_srcdir)/misc/modconfig --top_srcdir=$(top_srcdir)
+
+egg_test_run =  EGG_LANGDIR=$(top_srcdir)/language ./$(EGGEXEC) -v
+
+post_config  =  echo "" && \
+		echo "You can now compile the bot, using \"make\"." && \
+		echo ""
+
+post_iconfig =  $(modconf) update-depends && \
+		$(modconf) Makefile && \
+		(cd src/mod && $(MAKE_CONFIG) config) && \
+		$(modconf) Makefile
+
+egg_install_msg =  echo "" && \
+		   echo "Now run \"make install\" to install your bot." && \
+		   echo ""
 
 MAKE_MODEGG = $(MAKE) 'MAKE=$(MAKE)' 'CC=$(MOD_CC)' 'LD=$(MOD_LD)' \
-'STRIP=$(MOD_STRIP)' 'RANLIB=$(RANLIB)' 'CFLAGS=$(CFLAGS)' \
-'CPPFLAGS=$(CPPFLAGS)' 'TCLLIB=$(TCLLIB)' 'TCLLIBFN=$(TCLLIBFN)' \
-'XREQS=$(XREQS)' 'XLIBS=$(XLIBS)' 'EGGEXEC=$(EGGEXEC)' \
-'EGGBUILD=' 'MODOBJS='
+'STRIP=$(MOD_STRIP)' 'RANLIB=$(RANLIB)' 'CFLGS=$(CFLGS)' \
+'TCLLIB=$(TCLLIB)' 'TCLLIBFN=$(TCLLIBFN)' 'XREQS=$(XREQS)' \
+'XLIBS=$(XLIBS)' 'EGGEXEC=$(EGGEXEC)' 'EGGBUILD=' 'MODOBJS='
 
 MAKE_MODULES = $(MAKE) 'MAKE=$(MAKE)' 'CC=$(SHLIB_CC)' 'LD=$(SHLIB_LD)' \
-'STRIP=$(SHLIB_STRIP)' 'CFLAGS=$(CFLAGS)' 'CPPFLAGS=$(CPPFLAGS)'
+'STRIP=$(SHLIB_STRIP)' 'CFLGS=$(CFLGS)' 'XLIBS=$(XLIBS)' 'MOD_EXT=$(MOD_EXT)'
 
 MAKE_STATIC = $(MAKE) 'MAKE=$(MAKE)' 'CC=$(CC)' 'LD=$(LD)' \
-'STRIP=$(STRIP)' 'RANLIB=$(RANLIB)' 'CFLAGS=$(CFLAGS) -DSTATIC' \
-'CPPFLAGS=$(CPPFLAGS)' 'TCLLIB=$(TCLLIB)' 'TCLLIBFN=$(TCLLIBFN)' \
-'XREQS=$(XREQS)' 'XLIBS=$(XLIBS)' 'EGGEXEC=$(EGGEXEC)' \
-'EGGBUILD=(static version)' 'MODOBJS=mod/*.o'
+'STRIP=$(STRIP)' 'RANLIB=$(RANLIB)' 'CFLGS=$(CFLGS) -DSTATIC' \
+'TCLLIB=$(TCLLIB)' 'TCLLIBFN=$(TCLLIBFN)' 'XREQS=$(XREQS)' \
+'XLIBS=$(XLIBS)' 'EGGEXEC=$(EGGEXEC)' 'EGGBUILD=(static version)' \
+'MODOBJS=mod/*.o'
 
 MAKE_DEBEGG = $(MAKE) 'MAKE=$(MAKE)' 'CC=$(MOD_CC)' 'LD=$(MOD_LD) -g' \
-'STRIP=touch' 'RANLIB=$(RANLIB)' 'CFLAGS=-g3 $(DEBCFLAGS)' \
-'CPPFLAGS=$(CPPFLAGS)' 'TCLLIB=$(TCLLIB)' 'TCLLIBFN=$(TCLLIBFN)' \
-'XREQS=$(XREQS)' 'XLIBS=$(XLIBS)' 'EGGEXEC=$(EGGEXEC)' \
-'EGGBUILD=(debug version)' 'MODOBJS='
+'STRIP=touch' 'RANLIB=$(RANLIB)' 'CFLGS=-g3 $(DEBCFLAGS) $(CFLGS)' \
+'TCLLIB=$(TCLLIB)' 'TCLLIBFN=$(TCLLIBFN)' 'XREQS=$(XREQS)' \
+'XLIBS=$(XLIBS)' 'EGGEXEC=$(EGGEXEC)' 'EGGBUILD=(debug version)' 'MODOBJS='
 
 MAKE_DEBMODULES = $(MAKE) 'MAKE=$(MAKE)' 'CC=$(SHLIB_CC)' 'LD=$(SHLIB_LD)' \
-'STRIP=touch' 'CFLAGS=-g3 $(DEBCFLAGS)' 'CPPFLAGS=$(CPPFLAGS)'
+'XLIBS=$(XLIBS)' 'STRIP=touch' 'CFLGS=-g3 $(DEBCFLAGS) $(CFLGS)' \
+'MOD_EXT=$(MOD_EXT)'
 
 MAKE_SDEBUG = $(MAKE) 'MAKE=$(MAKE)' 'CC=$(CC)' 'LD=$(LD) -g' \
-'STRIP=touch' 'RANLIB=$(RANLIB)' 'CFLAGS=-g3 $(DEBCFLAGS) -DSTATIC' \
-'CPPFLAGS=$(CPPFLAGS)' 'TCLLIB=$(TCLLIB)' 'TCLLIBFN=$(TCLLIBFN)' \
-'XREQS=$(XREQS)' 'XLIBS=$(XLIBS)' 'EGGEXEC=$(EGGEXEC)' \
-'EGGBUILD=(static and debug version)' 'MODOBJS=mod/*.o'
+'STRIP=touch' 'RANLIB=$(RANLIB)' 'CFLGS=-g3 $(DEBCFLAGS) -DSTATIC $(CFLGS)' \
+'TCLLIB=$(TCLLIB)' 'TCLLIBFN=$(TCLLIBFN)' 'XREQS=$(XREQS)' 'XLIBS=$(XLIBS)' \
+'EGGEXEC=$(EGGEXEC)' 'EGGBUILD=(static and debug version)' 'MODOBJS=mod/*.o'
 
 MAKE_DEPEND = $(MAKE) 'MAKE=$(MAKE)' 'CC=$(CC)' 'LD=$(LD)' \
-'STRIP=$(STRIP)' 'CFLAGS=$(CFLAGS)' 'CPPFLAGS=$(CPPFLAGS)'
+'STRIP=$(STRIP)' 'CFLGS=$(CFLGS)'
+
+MAKE_CONFIG = $(MAKE) 'MAKE=$(MAKE)'
 
 MAKE_INSTALL = $(MAKE) 'MAKE=$(MAKE)' 'DEST=$(DEST)'
 
 all: @DEFAULT_MAKE@
 
-clean:
-	@rm -f $(EGGEXEC) *.so *.stamp core DEBUG *~
-	@cd doc; $(MAKE) clean
-	@cd scripts; $(MAKE) clean
-	@cd src; $(MAKE) clean
-	@cd src/md5; $(MAKE) clean
-	@cd src/mod; $(MAKE) clean
+eggclean:
+	@rm -f $(EGGEXEC) *.$(MOD_EXT) *.stamp core DEBUG *~
+	@cd doc && $(MAKE) clean
+	@cd scripts && $(MAKE) clean
+	@cd src && $(MAKE) clean
+	@cd src/md5 && $(MAKE) clean
+	@cd src/compat && $(MAKE) clean
+
+clean: eggclean
+	@cd src/mod && $(MAKE) clean
 
-distclean: clean
-	@rm -f Makefile doc/Makefile scripts/Makefile src/Makefile src/md5/Makefile src/mod/Makefile
+distclean: eggclean clean-modconfig
+	@cd src/mod && $(MAKE) distclean
+	@rm -f Makefile doc/Makefile scripts/Makefile src/Makefile src/md5/Makefile src/compat/Makefile src/mod/Makefile
 	@rm -f config.cache config.log config.status config.h lush.h
+	@rm -rf autom4te.cache
 
 distrib: distclean
 	@rm -f `find . \( -name '*~' -o -name '*#' -o -name '*.orig' \
@@ -127,66 +151,117 @@ distrib: distclean
 
 depend:
 	@cat /dev/null > lush.h
-	@cd src; $(MAKE_DEPEND) depend
-	@cd src/md5; $(MAKE_DEPEND) depend
-	@cd src/mod; $(MAKE_DEPEND) depend
+	@cd src && $(MAKE_DEPEND) depend
+	@cd src/md5 && $(MAKE_DEPEND) depend
+	@cd src/mod && $(MAKE_DEPEND) depend
+	@cd src/compat && $(MAKE_DEPEND) depend
+
+eggautoconf:
+	@$(modconf) eggautoconf
+
+config:
+	@$(modconf) modules-still-exist
+	@$(modconf) detect-modules
+	@$(modconf) update-depends
+	@$(modconf) Makefile
+	@cd src/mod && $(MAKE_CONFIG) config
+	@$(modconf) Makefile
+	@$(post_config)
+
+new-iconfig:
+	@$(modconf) modules-still-exist
+	@$(modconf) update-depends
+	@$(modconf) -n configure
+	@$(post_iconfig)
+	@$(post_config)
+
+iconfig:
+	@$(modconf) modules-still-exist
+	@$(modconf) detect-modules
+	@$(modconf) update-depends
+	@$(modconf) configure
+	@$(post_iconfig)
+	@$(post_config)
+
+clean-modconfig:
+	@rm -f .modules .known_modules
+
+conftest:
+	@if test ! -f .modules; then \
+		echo ""; \
+		echo "You have NOT configured the modules yet. This has to be done"; \
+		echo "before you can start compiling."; \
+		echo ""; \
+		echo "   Run \"make config\" or \"make iconfig\" now."; \
+		echo ""; \
+		exit 1; \
+	fi
+
+reconfig: clean-modconfig config
 
 eggdrop: modegg modules
 
 modegg: modtest
-	@cd src; $(MAKE_MODEGG) $(EGGEXEC)
+	@rm -f src/mod/mod.xlibs
+	@cd src && $(MAKE_MODEGG) $(EGGEXEC)
 	@echo ""
-	@./$(EGGEXEC) -v
+	@$(egg_test_run)
 	@ls -l $(EGGEXEC)
 
 modules: modtest
-	@cd src/mod; $(MAKE_MODULES) modules
+	@cd src/mod && $(MAKE_MODULES) modules
 	@echo ""
 	@echo "modules made:"
-	@ls -l *.so
+	@ls -l *.$(MOD_EXT)
+	@$(egg_install_msg)
 
 static: eggtest
 	@echo ""
 	@echo "Making module objects for static linking..."
 	@echo ""
-	@cd src/mod; $(MAKE_STATIC) static
+	@rm -f src/mod/mod.xlibs
+	@cd src/mod && $(MAKE_STATIC) static
 	@echo ""
 	@echo "Making core eggdrop for static linking..."
 	@echo ""
-	@cd src; $(MAKE_STATIC) $(EGGEXEC)
+	@cd src && $(MAKE_STATIC) $(EGGEXEC)
 	@echo ""
-	@./$(EGGEXEC) -v
+	@$(egg_test_run)
 	@ls -l $(EGGEXEC)
+	@$(egg_install_msg)
 
 debug: debegg debmodules
 
 debegg: modtest
-	@cd src; $(MAKE_DEBEGG) $(EGGEXEC)
+	@cd src && $(MAKE_DEBEGG) $(EGGEXEC)
 	@echo ""
-	@./$(EGGEXEC) -v
+	@$(egg_test_run)
 	@ls -l $(EGGEXEC)
 
 debmodules: modtest
-	@cd src/mod; $(MAKE_DEBMODULES) modules
+	@cd src/mod && $(MAKE_DEBMODULES) modules
 	@echo ""
 	@echo "modules made:"
-	@ls -l *.so
+	@ls -l *.$(MOD_EXT)
+	@$(egg_install_msg)
 
 sdebug: eggtest
 	@echo ""
 	@echo "Making module objects for static linking..."
 	@echo ""
-	@cd src/mod; $(MAKE_SDEBUG) static
+	@rm -f src/mod/mod.xlibs
+	@cd src/mod && $(MAKE_SDEBUG) static
 	@echo ""
 	@echo "Making core eggdrop for static linking..."
 	@echo ""
-	@cd src; $(MAKE_SDEBUG) $(EGGEXEC)
+	@cd src && $(MAKE_SDEBUG) $(EGGEXEC)
 	@echo ""
-	@./$(EGGEXEC) -v
+	@$(egg_test_run)
 	@ls -l $(EGGEXEC)
+	@$(egg_install_msg)
 
-eggtest:
-	@if [ -f EGGMOD.stamp ]; then \
+eggtest: conftest
+	@if test -f EGGMOD.stamp; then \
 		echo "You're trying to do a STATIC build of eggdrop when you've";\
 		echo "already run 'make' for a module build.";\
 		echo "You must first type \"make clean\" before you can build";\
@@ -195,7 +270,7 @@ eggtest:
 	fi
 	@echo "stamp" >EGGDROP.stamp
 
-modtest:
+modtest: conftest
 	@if [ -f EGGDROP.stamp ]; then \
 		echo "You're trying to do a MODULE build of eggdrop when you've";\
 		echo "already run 'make' for a static build.";\
@@ -231,17 +306,17 @@ install-start:
 		exit 1; \
 	fi
 	@echo ""
-	@./$(EGGEXEC) -v
+	@$(egg_test_run)
 	@echo
 	@echo "Installing in directory: '$(DEST)'."
 	@echo
 	@if test ! -d $(DEST); then \
 		echo "Creating directory: $(DEST)."; \
-		$(top_srcdir)/mkinstalldirs $(DEST); \
+		$(top_srcdir)/misc/mkinstalldirs $(DEST); \
 	fi
 
 install-bin:
-	@if test -f $(DEST)/$(EGGEXEC); then \
+	@if test -f $(DEST)/o$(EGGEXEC); then \
 		rm -f $(DEST)/o$(EGGEXEC); \
 	fi
 	@if test -h $(DEST)/$(EGGEXEC); then \
@@ -266,91 +341,102 @@ install-modules:
 		rm -rf $(DEST)/modules.old; \
 		mv -f $(DEST)/modules $(DEST)/modules.old; \
 	fi
-	@if test ! "x`echo *.so`" = "x*.so"; then \
+	@if test ! "x`echo *.$(MOD_EXT)`" = "x*.$(MOD_EXT)"; then \
 		if test ! -d $(DEST)/modules-$(EGGVERSION); then \
 			echo "Creating modules-$(EGGVERSION) directory and symlink."; \
-			$(top_srcdir)/mkinstalldirs $(DEST)/modules-$(EGGVERSION); \
+			$(top_srcdir)/misc/mkinstalldirs $(DEST)/modules-$(EGGVERSION); \
 		fi; \
 		(cd $(DEST) && $(LN_S) modules-$(EGGVERSION) modules); \
 		echo "Copying new modules."; \
-		for i in *.so; do \
+		for i in *.$(MOD_EXT); do \
 			$(INSTALL_PROGRAM) $$i $(DEST)/modules-$(EGGVERSION)/; \
 		done; \
 	fi
 
 install-data:
-	@$(INSTALL_DATA) eggdrop.conf.dist $(DEST)
-	@if test ! -f $(DEST)/motd; then \
-		$(INSTALL_DATA) motd $(DEST); \
+	@$(INSTALL_DATA) $(srcdir)/eggdrop.advanced.conf $(DEST)
+	@$(INSTALL_DATA) $(srcdir)/eggdrop.complete.conf $(DEST)
+	@$(INSTALL_DATA) $(srcdir)/eggdrop.simple.conf $(DEST)
+	@if test ! -d $(DEST)/logs; then \
+		echo "Creating 'logs' subdirectory."; \
+		$(top_srcdir)/misc/mkinstalldirs $(DEST)/logs; \
+		$(INSTALL_DATA) $(srcdir)/logs/CONTENTS $(DEST)/logs/; \
+	fi;
+	@if test ! -d $(DEST)/text; then \
+		echo "Creating 'text' subdirectory."; \
+		$(top_srcdir)/misc/mkinstalldirs $(DEST)/text; \
+	fi;
+	@if test ! -f $(DEST)/text/motd; then \
+		$(INSTALL_DATA) $(srcdir)/text/motd $(DEST)/text/; \
 	fi
-	@if test ! -f $(DEST)/telnet-banner; then \
-		$(INSTALL_DATA) telnet-banner $(DEST); \
+	@if test ! -f $(DEST)/text/banner; then \
+		$(INSTALL_DATA) $(srcdir)/text/banner $(DEST)/text/; \
 	fi
 
 install-help:
 	@echo "Copying help files."
-	@if test ! "x`echo help/*.help`" = "xhelp/*.help"; then \
+	@if test ! "x`echo $(srcdir)/help/*.help`" = "x$(srcdir)/help/*.help"; then \
 		if test ! -d $(DEST)/help; then \
 			echo "Creating 'help' subdirectory."; \
-			$(top_srcdir)/mkinstalldirs $(DEST)/help; \
+			$(top_srcdir)/misc/mkinstalldirs $(DEST)/help; \
 		fi; \
-		for i in help/*.help; do \
+		for i in $(srcdir)/help/*.help; do \
 			$(INSTALL_DATA) $$i $(DEST)/help/; \
 		done; \
 	fi
-	@if test ! "x`echo help/msg/*.help`" = "xhelp/msg/*.help"; then \
+	@if test ! "x`echo $(srcdir)/help/msg/*.help`" = "x$(srcdir)/help/msg/*.help"; then \
 		if test ! -d $(DEST)/help/msg; then \
 			echo "Creating 'help/msg' subdirectory."; \
-			$(top_srcdir)/mkinstalldirs $(DEST)/help/msg; \
+			$(top_srcdir)/misc/mkinstalldirs $(DEST)/help/msg; \
 		fi; \
-		for i in help/msg/*.help; do \
+		for i in $(srcdir)/help/msg/*.help; do \
 			$(INSTALL_DATA) $$i $(DEST)/help/msg/; \
 		done; \
 	fi
-	@if test ! "x`echo help/set/*.help`" = "xhelp/set/*.help"; then \
+	@if test ! "x`echo $(srcdir)/help/set/*.help`" = "x$(srcdir)/help/set/*.help"; then \
 		if test ! -d $(DEST)/help/set; then \
 			echo "Creating 'help/set' subdirectory."; \
-			$(top_srcdir)/mkinstalldirs $(DEST)/help/set; \
+			$(top_srcdir)/misc/mkinstalldirs $(DEST)/help/set; \
 		fi; \
-		for i in help/set/*.help; do \
+		for i in $(srcdir)/help/set/*.help; do \
 			$(INSTALL_DATA) $$i $(DEST)/help/set/; \
 		done; \
 	fi
-	@cd src/mod/; $(MAKE_INSTALL) install-help
+	@cd src/mod/ && $(MAKE_INSTALL) install-help
 
 install-language:
 	@echo "Copying language files."
-	@if test ! "x`echo language/*.lang`" = "xlanguage/*.lang"; then \
+	@if test ! "x`echo $(srcdir)/language/*.lang`" = "x$(srcdir)/language/*.lang"; then \
 		if test ! -d $(DEST)/language; then \
 			echo "Creating 'language' subdirectory."; \
-			$(top_srcdir)/mkinstalldirs $(DEST)/language; \
+			$(top_srcdir)/misc/mkinstalldirs $(DEST)/language; \
 		fi; \
-		for i in language/*.lang; do \
+		for i in $(srcdir)/language/*.lang; do \
 			$(INSTALL_DATA) $$i $(DEST)/language/; \
 		done; \
 	fi
-	@cd src/mod/; $(MAKE_INSTALL) install-language
+	@cd src/mod && $(MAKE_INSTALL) install-language
 
 install-filesys:
 	@if test ! -d $(DEST)/filesys; then \
 		echo "Creating a skeletal filesys subdirectory."; \
-		$(top_srcdir)/mkinstalldirs $(DEST)/filesys; \
-		$(top_srcdir)/mkinstalldirs $(DEST)/filesys/incoming; \
+		$(top_srcdir)/misc/mkinstalldirs $(DEST)/filesys; \
+		$(top_srcdir)/misc/mkinstalldirs $(DEST)/filesys/incoming; \
 	fi
 
 install-doc:
-	@$(INSTALL_DATA) README $(DEST)
-	@cd doc/; $(MAKE_INSTALL) install
+	@$(INSTALL_DATA) $(srcdir)/README $(DEST)
+	@cd doc/ && $(MAKE_INSTALL) install
 
 install-scripts:
-	@cd scripts/; $(MAKE_INSTALL) install
+	@cd scripts/ && $(MAKE_INSTALL) install
 
 install-end:
 	@echo
 	@echo "Installation completed."
 	@echo ""
 	@echo "You MUST ensure that you edit/verify your configuration file."
-	@echo "'eggdrop.conf.dist' lists current options."
+	@echo "Use one of the three configuration files (eggdrop.simple.conf, eggdrop.advanced.conf and eggdrop.complete.conf) distributed with your bot."
 	@echo ""
 	@echo "Remember to change directory to $(DEST) before you proceed."
 	@echo ""

+ 586 - 0
README

@@ -0,0 +1,586 @@
+Readme
+Last revised: June 5, 2002
+     _________________________________________________________________
+
+                                   Readme
+
+
+  Please at least SKIM this document before asking questions. In fact, READ
+  IT if you've never successfully set up an Eggdrop bot before. PLEASE! READ
+  IT!
+
+  Contents
+
+    0. Important notice
+    1. What is Eggdrop?
+    2. How do I get Eggdrop?
+       2a. How to get the latest version of Eggdrop via CVS
+    3. Quick startup
+    4. Upgrading
+       4a. Upgrading from a pre-1.3 version to 1.6
+       4b. Upgrading from an older 1.3/1.4/1.5/1.6 version to a newer one
+    5. Command line
+    6. Frequently Asked Questions
+       6a. What do I do if I get the error "User file not found"?
+       6b. My Eggdrop won't run; It just says "Can't find your hostname!"
+       6c. What the Heck is Tcl?
+       6d. My bot dies and the last entry in the logfile is "Received terminate
+           signal". What does that mean and can I prevent it?
+       6e. My compile dies at the last minute with "LD fatal signal 11"!
+       6f. Someone else set up a bot I don't like. Are there any backdoors I
+           can use to take their bot down?
+       6g. What are modules?
+       6h. Can I compile Eggdrop without dynamic modules?
+           6h1. Do I still need to "loadmodule" modules?
+       6i. Where can I get a pre-compiled Eggdrop for my computer?
+       6j. I get "Makefile:3 : invalid operator" or some such thing when I
+           try to "make".
+       6k. When I "tclsh scripts/weed <userfile> c" It barfs chunks at me
+           and dies.
+       6l. I get "ld-elf.so.1: Shared object "libtcl80.so.1" not found" or
+           "eggdrop: error in loading shared libraries / libtcl8.1.so: cannot
+           open shared object file: No such file or directory" when I try to
+           start my bot.
+       6m. I get a whole pile of "unresolved symbol 'Tcl_AppendResult'" (or
+           some other symbol) when I try to load a module.
+    7. Setting up a crontab
+       7a. Setting up a crontab using autobotchk
+    8. Boring legal stuff
+    9. Mailing list
+   10. Documentation
+   11. Obtaining help
+
+     _________________________________________________________________
+
+
+  (0) NOTICE
+
+    Please read this file carefully before trying to set up Eggdrop. Also,
+    make SURE that you select your +n (owner) users wisely! They have 100%
+    access to your bot and account! ONLY GIVE THIS POWER TO SOMEONE YOU
+    TRUST COMPLETELY!!
+
+
+  (1) WHAT IS EGGDROP?
+
+    Eggdrop is the world's most popular Internet Relay Chat (IRC) bot; it is
+    freely distributable under the GNU General Public License (GPL). Eggdrop
+    is a feature rich program designed to be easily used and expanded upon by
+    both novice and advanced IRC users on a variety of hardware and software
+    platforms.
+
+    An IRC bot is a program that sits on an IRC channel and preforms automated
+    tasks while looking just like a normal user on the channel. Some of these
+    functions include protecting the channel from abuse, allowing privileged
+    users to gain op or voice status, logging channel events, providing
+    information, hosting games, etc.
+
+    One of the features that makes Eggdrop stand out from other bots is module
+    and Tcl scripting support. With scripts and modules, you can make the bot
+    preform almost any task you want. They can do anything from preventing
+    floods to greeting users and banning advertisers from channels.
+
+    You can also link multiple Eggdrop bots together to form a botnet. This
+    can allow bots to op each other securely, control floods efficiently, and
+    even link channels across multiple IRC networks. It also allows the
+    Eggdrops share user lists, ban lists, exempt/invite lists, and ignore
+    lists with other bots if userfile sharing is enabled. This allows users
+    to have the same access on every bot on your botnet. It also allows the
+    bots to distribute tasks such as opping and banning users. See doc/BOTNET
+    for information on setting up a botnet.
+
+    Eggdrop is always being improved and adjusted because there are bugs to
+    be fixed and features to be added (if the users demand them, and they make
+    actually sense). In fact, it existed for several years as v0.7 - v0.9
+    before finally going 1.0. This version of Eggdrop is part of the 1.6 tree.
+    A valiant effort has been made to chase down and destroy bugs.
+
+    This README file contains information about how to get Eggdrop, command
+    line options for Eggdrop, what you may need to do when upgrading from
+    older versions, a list of frequently asked questions, how to set up a
+    crontab, some boring legal stuff, info about the mailing list (a great
+    place to ask questions, and a good place to report bugs, too), some basics
+    about CVS usage, and some channels where you might get help with Eggdrop.
+
+
+  (2) HOW TO GET EGGDROP
+
+    Before you can compile Eggdrop, you need to have Tcl installed on your
+    system. Most systems should have Tcl on them by now -- you can check by
+    trying the command "tclsh". If it works, you will be given a "%" prompt,
+    and you can type "exit" to exit the program. This means Tcl is installed
+    on your system. If tclsh doesn't load, then Tcl probably isn't on your
+    system, and you will need to install it. The best ftp site for Tcl is
+    ftp://ftp.scriptics.com/pub/tcl.
+
+    Tcl comes with the most distributions of Linux. HOWEVER, the one that comes
+    on Slackware 3.0 is goofed up and you'll have to re-install it for yourself
+    to get it working.
+
+    Currently, the 1.6 tree of Eggdrop is developed at eggheads.org. You can
+    get the latest version of Eggdrop from the following url:
+
+      http://www.geteggdrop.com
+
+    You might try www.eggheads.org for help and information.
+
+
+  (2a) CVS USAGE
+
+    You can obtain the VERY LATEST version of Eggdrop, that is still under
+    development, by using CVS. CVS means 'Concurrent Versions System' and is
+    a tool for developers to always keep source code up to date. Try 'man cvs'
+    on your shell for more information about CVS.
+
+    This is intended only for users that know a good bit about Eggdrop. Be
+    aware that the versions of Eggdrop that you get via CVS are still being
+    developed, and may be buggy. The Eggheads devteam will in NO WAY take
+    any responsibility for whatever might happen to you or your shell if
+    you use a CVS version of Eggdrop.
+
+    To obtain Eggdrop over CVS, do as follows:
+
+      1. Log into your shell.
+
+      2. Type: 'export
+         CVSROOT=:pserver:anonymous@cvs.eggheads.org:/usr/local/cvsroot'.
+
+      3. Type 'cvs login'.
+
+      4. Press <enter> when prompted for a password.
+
+      5. In your home dir, type 'cvs checkout eggdrop1.6'
+
+      6. In ~/eggdrop1.6, you should have a copy of the latest CVS version
+         of Eggdrop.
+
+    Notes:
+
+      o You can 'cvs logout', but you don't need to.
+
+      o You don't need to go through this whole process every time. If you
+        want to get a CVS version of Eggdrop at a later time, you can just
+        'cd ~/eggdrop1.6' and type 'cvs update -dAP'.
+
+      o If you experience errors when using 'export', you might be using tclsh
+        as a shell. If so, try using the command 'setenv' instead of 'export':
+
+          setenv CVSROOT :pserver:anonymous@cvs.eggheads.org:/usr/local/cvsroot
+
+
+  (3) QUICK STARTUP
+
+    Please see the 'INSTALL' file AFTER you finish reading this file.
+
+
+  (4) UPGRADING
+
+
+  (4a) UPGRADING FROM A PRE-1.3 VERSION TO 1.6
+
+    #### BACK UP YOUR USERFILE ####
+
+    We can't stress this enough. If you are upgrading and you have even a
+    slight possibility of downgrading again later, you will HAVE to back up
+    your userfile, or you will lose it. v1.3 of Eggdrop radically changed a
+    lot of things.
+
+    There are many major changes between v0.9, v1.0, v1.1 and v1.6, so PAY
+    ATTENTION to this part if you have a v0.9, 1.0 or 1.1 bot currently. If
+    you're just starting out, you can skip this section.
+
+    If you run share bots, you will need to upgrade them all at the same time
+    because of the new userfile format. Older bots will be able to link in,
+    but will not get or send a userfile. MAKE A NEW CONFIG FILE from the
+    example; there are some radical changes.
+
+    If you are upgrading from 0.9/1.0 to 1.6, just redo the whole thing.
+    Absolutely everything has changed, including the userfile and config file
+    formats.
+
+    If you are upgrading from 1.1/1.2 to 1.6, you will likely want to redo
+    the config file, as much as changed. BACK UP! You will need to run 'tclsh
+    scripts/weed/<userfile> c' to convert your userfile from v3 (1.1/1.2) to
+    v4 (1.3/1.4/1.5/1.6).
+
+
+  (4b) UPGRADING FROM AN OLDER 1.3/1.4/1.5/1.6 VERSION TO A NEWER 1.6 VERSION
+
+    If you followed the 'INSTALL' file and did a 'make install' (or 'make
+    install DEST="path"') after 'make', this will be pretty easy. Just upload
+    the new eggdrop1.6.x.tar.gz file to your home dir on your shell, gunzip
+    and untar it, and type 'cd ~/eggdrop1.6.x'. Next, type './configure',
+    'make config' or 'make iconfig', then 'make'. Then, kill the bot ('.die'
+    on the party line), and 'make install' to the same directory your bot
+    is currently in. After that, you can just restart your bot. You may wish
+    to delete the old Eggdrop executable and modules as well, especially if
+    you have limited disk space.
+
+    You should read through the new eggdrop.complete.conf file for all the new
+    options in Eggdrop 1.6.x if you are upgrading from 1.3.x or 1.4.x. You can
+    copy and paste any of these settings into you current conf file if you do
+    not want to use the default settings.
+
+
+  (5) COMMAND LINE
+
+    Eggdrop has some command-line options -- not many, because most things
+    should be defined through the config file. However, sometimes you may
+    want to start up the bot in a different mode, and the command-line
+    options let you do that. Basically, the command line for Eggdrop is:
+
+      % eggdrop [options] [config-file]
+
+    The options available are:
+
+      -n: Don't background. Normally, Eggdrop will move itself into the
+          background when you start it up, meaning you'll get another shell
+          prompt, and you can do other things while the bot is running. With
+          -n, you won't return to the shell prompt until the bot exits (which
+          won't normally happen until it's killed). By default, -n will send
+          all log entries to the console.
+
+      -nt: Don't background, use terminal. This is just like -n, except that
+           instead of seeing log entries, your console will simulate a DCC
+           chat with the bot.
+
+      -nc: Don't background, show channel info. This is just like -n, except
+           that instead of seeing log entries, every 10 seconds your screen
+           will clear and you will see the current channel status, sort of
+           like "top".
+
+      -m: Create userfile. If you don't have a userfile, this will make Eggdrop
+          create one and give owner status to the first person that introduces
+          himself or herself to it. You'll need to do this when you first set
+          up your bot.
+
+      -v: Show version info, then quit.
+
+    Most people never use any of the options except -m, and you usually only
+    need to use that once.
+
+
+  (6) FREQUENTLY ASKED QUESTIONS (or "Why doesn't this thing work?")
+
+    6a. WHAT DO I DO IF I GET THE ERROR "USER FILE NOT FOUND"?
+
+      1. Run Eggdrop with the "-m" option (i.e., "eggdrop -m eggdrop.conf").
+
+      2. Go to IRC and send "hello" to your bot (i.e., "/msg mybot hello").
+
+      3. You will become an owner on your bot. You can leave the bot running
+         (nobody else will become an owner if they say "hello"), but in the
+         future, don't use the "-m" option when running the bot.
+
+    6b. MY EGGDROP WON'T RUN; IT JUST SAYS "CAN'T FIND YOUR HOSTNAME!"
+
+      Your machine is set up strangely, and Eggdrop can't figure out its
+      network hostname. You can get around this by setting the my-ip setting
+      in the config file correctly.
+
+    6c. WHAT THE HECK IS Tcl?
+
+      Tcl is a scripting language written by John Ousterhout. It's much better
+      than most "built-in" script languages (like the one in ircII) and is
+      meant to be linked with anything needing a  scripting language, so I
+      linked it with Eggdrop. The file "tcl-commands.doc" in the doc directory
+      contains a list of additional Tcl commands provided by Eggdrop. There
+      are also several example scripts in the scripts/ directory, and one in
+      the doc directory called first_script.txt. Hundreds of scripts floating
+      around on the ftp/web sites if you like working by example (which is
+      typically the best way).
+
+    6d. MY BOT DIES, AND THE LAST ENTRY IN THE LOGFILE IS "RECEIVED TERMINATE
+        SIGNAL". WHAT DOES THAT MEAN, AND CAN I PREVENT IT?
+
+      There's nothing you can do to prevent it. It means the system
+      administrator is killing the Eggdrop process. Most of the time, it's an
+      automatic thing that happens when the system is being rebooted, so it's
+      harmless. If you have a crontab running, the bot will get restarted when
+      the system is back online. Occasionally, the system administrator will
+      kill the bot manually. For example, if he/she doesn't want bots running
+      on the system.
+
+    6e. MY COMPILE DIES AT THE LAST MINUTE WITH "LD FATAL SIGNAL 11"!
+      
+      See doc/compiling.FAQ.
+
+    6f. SOMEONE ELSE SET UP A BOT I DON'T LIKE. ARE THERE ANY BACKDOORS I CAN
+        USE TO TAKE THEIR BOT DOWN?
+
+      No, there have never been any backdoors and there never will be, so
+      please stop asking. Every once in a while, someone finds a way to
+      exploit a bug in Eggdrop, but we fix these bugs as soon as we find out
+      about them. If you want to bring down someone else's bot, you will not
+      have my/our help.
+
+    6g. WHAT ARE MODULES?
+
+      Modules are a way of adding extra features to the bot, much like Tcl
+      scripts, without requiring the bot to be recompiled. See doc/MODULES
+      for more information.
+
+    6h. CAN I COMPILE EGGDROP WITHOUT DYNAMIC MODULES?
+
+       Yes, you can. If the configure script detects that your system CAN'T
+       run modules, it will setup 'make' to link the modules in statically
+       for you. You can choose this option yourself by using 'make static'.
+       You can also try to compile dynamic modules on a static-only system
+       by using 'make eggdrop'.
+
+    6h1. DO I STILL NEED TO 'loadmodule' MODULES?
+
+      YES, when you compile statically, all the modules are linked into the
+      main executable. HOWEVER, they are not enabled until you use loadmodule
+      to enable them, hence you get nearly the same functionality with static
+      modules as with dynamic modules.
+
+    6i. WHERE CAN I GET A PRE-COMPILED EGGDROP FOR MY COMPUTER?
+
+      It is HIGHLY recommended AGAINST using pre-compiled Eggdrops from
+      un-trusted sources. Eggdrop has been a regular target for hacking and
+      crashing. Distribution of pre-compiled (binary) versions of Eggdrop are
+      the easiest way for hackers to provide you with the easiest (and most
+      dangerous) way of gaining access to, not only your bot, but to your
+      computer account directly. Don't advertise your pre-compiled Eggdrop
+      binary sites on the Eggdrop list either. =P
+
+    6j. I GET 'Makefile:3 :invalid operator' OR SOME-SUCH-THING WHEN I TRY
+        TO 'make'.
+
+      Try 'gmake'.
+
+    6k. WHEN I 'tclsh scripts/weed <userfile> c' IT BARFS CHUNKS AT ME AND
+        DIES. :(
+
+      Upgrade your Tcl. You are probably using Tcl 7.5 or earlier. Some of the
+      commands in weed require Tcl7.6 to run, so either upgrade it or remove
+      the offending lines from you userfile manually (those starting with '.'
+      generally) and accept the loss of that data.
+
+    6l. I GET "ld-elf.so.1: Shared object "libtcl80.so.1" not found" or
+        "eggdrop: error in loading shared libraries libtcl8.1.so: \
+        cannot open shared object file: No such file or directory" WHEN I TRY
+        TO START MY BOT.
+
+      './configure' is looking in the wrong place for Tcl; it looks like it
+      compiled with one version of Tcl and tries to load another. Maybe your
+      sysadmin upgraded Tcl and didn't tell you. In that case, you should just
+      need to recompile your bot.
+
+      Maybe, when upgrading, he didn't clean the old version of Tcl and
+      './configure' is looking for the files in the wrong places, or trying
+      to use different versions of tcl.h and libtcl*. Smack your admin and
+      have him install Tcl properly. ;)
+
+      You can also try:
+
+        ./configure --with-tcllib=<path-to-tcl-lib>
+                    --with-tclinc=<path-to-tcl-inc>
+
+      This will tell configure where to look for the Tcl files.
+
+      Try looking for libtcl by:
+
+        ls /usr/lib/libtcl*
+        ls /usr/local/lib/libtcl*
+
+      Try looking for tcl.h by:
+
+        ls /usr/include/tcl.h
+        ls /usr/local/include/tcl.h
+
+        If everything else fails, try to install Tcl to your home dir ;)
+        (Suggested by dw@Undernet, dw@lixom.nu)
+
+    6m. I GET A WHOLE PILE OF "Unresolved symbol 'Tcl_AppendResult'" (OR SOME
+        OTHER SYMBOL) WHEN I TRY TO LOAD A MODULES.
+
+      POSSIBILITY A: See section 12.
+
+      POSSIBILITY B:
+
+        Some of the standard libraries have been compiled for static linking
+        only on your machine, you have 3 options:
+
+          1. If it's your own machine, recompile Tcl using dynamic linking by
+             using './configure --enable-shared' when you configure Tcl (not
+             the bot) and then remake, and reinstall.
+
+          2. If it's not your machine, you make have to resort to 'make static'
+             and 'make install DEST="path"' to make and install your bot.
+
+          3. If you are of a more aggressive sense of mind, go beat the
+             stuffing out of your admin for having lame static libraries. :)
+
+
+  (7) SETTING UP A CRONTAB
+
+    Eggdrop has become more stable with time, thanks mostly to people
+    reporting bug details and helping find places where it crashes. However,
+    there are still a -few- places where things aren't perfect. Few, if any,
+    things in life are.
+
+    Also, most systems go down from time to time. These things cause your bot
+    to disappear from IRC, and you have to restart it.
+
+    Eggdrop comes with a shell script called 'botchk' that will help keep the
+    bot online. It will make the machine check every ten minutes to make sure
+    your bot is still running. To use it, you have to add a line to your
+    crontab. First, edit 'botchk' and change the directory and command line
+    parameters so that it will be able to start up your bot. Then, add this
+    line to your crontab:
+
+      0,10,20,30,40,50 * * * * /home/mydir/botchk
+
+    If you don't want to get e-mails from cron, use this:
+
+      0,10,20,30,40,50 * * * * /home/mydir/botchk >/dev/null 2>&1
+
+    Naturally, you need to change the path to the correct path for botchk. If
+    you've never used crontab before, here is a simple way to add that line:
+
+      1. Create a new file called 'mycron' and put the above line into it.
+
+      2. From your shell prompt, type '% crontab mycron'.
+
+    That will create a new crontab entry for you with a line that runs botchk
+    every ten minutes. Botchk will then restart the bot when necessary (and
+    send you email informing you).
+
+
+  (7a) SETTING UP A CRONTAB USING AUTOBOTCHK
+
+    Included with your Eggdrop is an Eggdrop utility called 'autobotchk'.
+    Using autobotchk is probably the fastest way of creating your botchk and
+    crontabbing it with just a few required steps:
+
+      1. Type 'cp scripts/autobotchk ..'.
+
+      2. Type './autobotchk <Eggdrop config file>'.
+
+    This will hopefully crontab your bot using the default setup. If you want
+    a list of autobotchk options, type './autobotchk'. An example with options
+    would be:
+
+      ./autobotchk <Eggdrop config file> -noemail -5
+
+    This would setup crontab to run the botchk every 5 minutes and also to
+    not send you e-mail saying that it restarted your bot.
+
+
+  (8) BORING LEGAL STUFF
+
+    The Eggdrop bot is copyright (C) by Robey Pointer. As of January, 1997,
+    Eggdrop is distributed according to the GNU General Public License. There
+    should be a copy of this license in the file 'COPYING'. If not, write to
+    the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    As of eggdrop1.3.28, all changes made by the Eggheads development team to
+    the Eggdrop source code and any related files are copyright (C) by
+    Eggheads. The source code will still be distributed according to the GNU
+    General Public License as Robey Pointer did in the past.
+
+    Releases previous to 1.0m were made using a different licensing scheme.
+    You may, at your option, use the GNU General Public License on those
+    versions (instead of the license packaged with them) with my blessing.
+    For any versions bearing a copyright date of 1997 or later, you have
+    no choice -- you must use the GNU General Public License.
+
+    The files "match.c", "net.c", and "blowfish.c" are exempt from the above
+    restrictions. "match.c" is original code by Chris Fuller (email:
+    crf@cfox.bchs.uh.edu) and has been placed by him into the public domain.
+    "net.c" is by me, and I [who?] also choose to place it in the public
+    domain. "blowfish.c" is by various sources and is in the public domain
+    as well. All 3 files contain useful functions that could easily be
+    ported to other applications.
+
+    Tcl is by John Ousterhout and is in no way affiliated with Eggdrop. It
+    likely has its own set of copyrights and whatnots.
+
+    There is no warranty, implied or whatever. You use this software at your
+    own risk, no matter what purpose you put it to.
+
+
+  (9) MAILING LIST
+
+    There are currently a couple of mailing lists about Eggdrop.
+    eggheads@eggheads.org is the one relevant for posts about Eggdrop 1.4 and
+    up (suggestions, help, etc).
+
+    To subscribe to the eggheads mailing list, send e-mail to
+    eggheads-request@eggheads.org. In the body of the message, put "subscribe
+    eggheads". You can also go to the following url:
+
+      http://scrambled.eggheads.org/mailman/listinfo/eggheads
+
+    ### DO NOT SEND ROBEY EMAIL ABOUT EGGDROP! ###
+
+    Robey is no longer developing the Eggdrop code, so don't bother e-mailing
+    him. If you have a serious problem, email the eggheads mailing list and
+    it will get to the coders.
+
+    Please, before posting to this list, see what things are like. When you do
+    post, read over your post for readability, spelling, and grammar mistakes.
+    Obviously, we're all human (or are we?) and we all make mistakes (heck,
+    look at this document! ;).
+
+    Open discussion and debate is integral to change and progress. Don't flame
+    others over mere form (grammar and spelling), or even substantive issues
+    for that matter. Please read and follow the mailing list rules.
+
+    The eggheads@eggheads.org mailing list is not dedicated to those all too
+    common questions we have all seen on other lists... For example:
+
+      o "Why does my bot say this: Please edit your config file."
+      o "How do I telnet my bot?"
+      o "Where do I get Eggdrop for windows??????"
+
+    Technical questions, your thoughts or suggestions on new features being
+    added to Eggdrop, things that should be removed or fixed, amazing problems
+    that even stump the guru's, etc. are what we want to see here.
+
+    Bug reports should be sent to bugs@eggheads.org. Please read and fill out
+    the BUG-REPORT file in the doc directory.
+
+    DO NOT SEND HTML E-MAILS TO ANY OF THE EGGHEADS.ORG MAILING LISTS. ANYONE
+    CAUGHT SENDING HTML E-MAILS TO ONE OF THESE LISTS WILL BE REMOVED
+    IMMEDIATELY!
+
+
+  (10) DOCUMENTATION
+
+    We're trying to keep the documentation up to date. If you feel that
+    anything is missing here or that anything should be added, etc, please
+    email eggheads@eggheads.org about it. Thank you.
+
+
+  (11) OBTAINING HELP
+
+    You can obtain help with Eggdrop in the following IRC channels:
+
+      Undernet - #eggdrop, #eggies
+      EFnet - #egghelp, #eggfaq
+      IRCnet - #eggdrop
+      DALnet - #eggdrop, #botcentral
+      OPN - #eggdrop, #egghelp
+      QuakeNet - #eggdrop
+
+    If you plan to ask questions in any of the above channels, you should be
+    familiar with and follow IRC etiquette.
+
+      o Don't type using CAPITAL letters, colors, or bold.
+
+      o Don't use  "!" and "?" excessively.
+
+      o Don't /msg people without their permission.
+
+      o Don't repeat or paste large amounts of text to the channel.
+
+    If there are any other serious Eggdrop related channels that should be
+    added to the above list, please let us know.
+
+  ________________________________________________________________________
+
+Copyright (C) 1997 Robey Pointer
+Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team

+ 15 - 2
acconfig.h

@@ -1,8 +1,11 @@
+#ifndef _EGG_CONFIG_H
+#define _EGG_CONFIG_H
+@TOP@
 /* 
  * acconfig.h
  *   template file autoheader uses when building config.h.in
  * 
- * $Id: acconfig.h,v 1.5 2000/01/08 22:38:19 per Exp $
+ * $Id: acconfig.h,v 1.10 2001/11/11 20:24:44 guppy Exp $
  */
 
 /* Define if modules will work on your system  */
@@ -29,6 +32,9 @@
 /* Define if running under cygwin  */
 #undef CYGWIN_HACKS
 
+/* Define if you have a version of libsafe with a broken sscanf */
+#undef LIBSAFE_HACKS
+
 /* Define if we need dlopen (for module support)  */
 #undef HAVE_DLOPEN
 
@@ -41,5 +47,12 @@
 /* Define for Tcl that has threads  */
 #undef HAVE_TCL_THREADS
 
-/* Defines the current eggdrop version */
+/* Defines the current eggdrop version  */
 #undef EGG_VERSION
+
+/* Defines extension of eggdrop modules  */
+#undef EGG_MOD_EXT
+
+@BOTTOM@
+
+#endif /* !_EGG_CONFIG_H */

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 391 - 204
aclocal.m4


+ 159 - 99
config.h.in

@@ -1,40 +1,12 @@
-/* config.h.in.  Generated automatically from configure.in by autoheader.  */
-
-/* Define if on AIX 3.
-   System headers sometimes define this.
-   We just want to avoid a redefinition error message.  */
-#ifndef _ALL_SOURCE
-#undef _ALL_SOURCE
-#endif
-
-/* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
-#undef HAVE_SYS_WAIT_H
-
-/* Define as __inline if that's what the C compiler calls it.  */
-#undef inline
-
-/* Define if on MINIX.  */
-#undef _MINIX
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef pid_t
-
-/* Define if the system does not provide POSIX.1 features except
-   with this defined.  */
-#undef _POSIX_1_SOURCE
-
-/* Define if you need to in order for stat and other things to work.  */
-#undef _POSIX_SOURCE
-
-/* Define if you have the ANSI C header files.  */
-#undef STDC_HEADERS
-
-/* Define if you can safely include both <sys/time.h> and <time.h>.  */
-#undef TIME_WITH_SYS_TIME
-
-/* Define if your processor stores words with the most significant
-   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
-#undef WORDS_BIGENDIAN
+/* config.h.in.  Generated from configure.in by autoheader.  */
+#ifndef _EGG_CONFIG_H
+#define _EGG_CONFIG_H
+/* 
+ * acconfig.h
+ *   template file autoheader uses when building config.h.in
+ * 
+ * $Id: config.h.in,v 1.24 2001/12/20 00:10:43 guppy Exp $
+ */
 
 /* Define if modules will work on your system  */
 #undef MODULES_OK
@@ -60,6 +32,9 @@
 /* Define if running under cygwin  */
 #undef CYGWIN_HACKS
 
+/* Define if you have a version of libsafe with a broken sscanf */
+#undef LIBSAFE_HACKS
+
 /* Define if we need dlopen (for module support)  */
 #undef HAVE_DLOPEN
 
@@ -72,119 +47,204 @@
 /* Define for Tcl that has threads  */
 #undef HAVE_TCL_THREADS
 
-/* Defines the current eggdrop version */
+/* Defines the current eggdrop version  */
 #undef EGG_VERSION
 
-/* The number of bytes in a char.  */
-#undef SIZEOF_CHAR
+/* Defines extension of eggdrop modules  */
+#undef EGG_MOD_EXT
 
-/* The number of bytes in a int.  */
-#undef SIZEOF_INT
 
-/* The number of bytes in a long.  */
-#undef SIZEOF_LONG
-
-/* The number of bytes in a short int.  */
-#undef SIZEOF_SHORT_INT
+/* Define if you have the `clock' function. */
+#undef HAVE_CLOCK
 
-/* Define if you have the bzero function.  */
-#undef HAVE_BZERO
+/* Define if you have the <dirent.h> header file, and it defines `DIR'. */
+#undef HAVE_DIRENT_H
 
-/* Define if you have the clock function.  */
-#undef HAVE_CLOCK
+/* Define if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
 
-/* Define if you have the dlopen function.  */
+/* Define if you have the `dlopen' function. */
 #undef HAVE_DLOPEN
 
-/* Define if you have the dprintf function.  */
+/* Define if you have the `dprintf' function. */
 #undef HAVE_DPRINTF
 
-/* Define if you have the getdtablesize function.  */
+/* Define if you have the `fsync' function. */
+#undef HAVE_FSYNC
+
+/* Define if you have the `getdtablesize' function. */
 #undef HAVE_GETDTABLESIZE
 
-/* Define if you have the getrusage function.  */
+/* Define if you have the `getrusage' function. */
 #undef HAVE_GETRUSAGE
 
-/* Define if you have the random function.  */
+/* Define if you have the `inet_aton' function. */
+#undef HAVE_INET_ATON
+
+/* Define if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have the `isascii' function. */
+#undef HAVE_ISASCII
+
+/* Define if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define if you have the `dld' library (-ldld). */
+#undef HAVE_LIBDLD
+
+/* Define if you have the `dns' library (-ldns). */
+#undef HAVE_LIBDNS
+
+/* Define if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define if you have the `random' function. */
 #undef HAVE_RANDOM
 
-/* Define if you have the rename function.  */
+/* Define if you have the `rename' function. */
 #undef HAVE_RENAME
 
-/* Define if you have the setpgid function.  */
+/* Define if you have the `setpgid' function. */
 #undef HAVE_SETPGID
 
-/* Define if you have the sigaction function.  */
+/* Define if you have the `sigaction' function. */
 #undef HAVE_SIGACTION
 
-/* Define if you have the sigemptyset function.  */
+/* Define if you have the `sigemptyset' function. */
 #undef HAVE_SIGEMPTYSET
 
-/* Define if you have the snprintf function.  */
+/* Define if you have the `snprintf' function. */
 #undef HAVE_SNPRINTF
 
-/* Define if you have the srandom function.  */
+/* Define if you have the `srandom' function. */
 #undef HAVE_SRANDOM
 
-/* Define if you have the strcasecmp function.  */
-#undef HAVE_STRCASECMP
-
-/* Define if you have the uname function.  */
-#undef HAVE_UNAME
+/* Define if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
 
-/* Define if you have the vsnprintf function.  */
-#undef HAVE_VSNPRINTF
+/* Define if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
 
-/* Define if you have the vsprintf function.  */
-#undef HAVE_VSPRINTF
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
 
-/* Define if you have the <dirent.h> header file.  */
-#undef HAVE_DIRENT_H
+/* Define if you have the <std_args.h> header file. */
+#undef HAVE_STD_ARGS_H
 
-/* Define if you have the <dlfcn.h> header file.  */
-#undef HAVE_DLFCN_H
+/* Define if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
 
-/* Define if you have the <ndir.h> header file.  */
-#undef HAVE_NDIR_H
+/* Define if you have the `strftime' function. */
+#undef HAVE_STRFTIME
 
-/* Define if you have the <std_args.h> header file.  */
-#undef HAVE_STD_ARGS_H
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
 
-/* Define if you have the <stdarg.h> header file.  */
-#undef HAVE_STDARG_H
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
 
-/* Define if you have the <strings.h> header file.  */
-#undef HAVE_STRINGS_H
+/* Define if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
 
-/* Define if you have the <sys/dir.h> header file.  */
+/* Define if you have the <sys/dir.h> header file, and it defines `DIR'. */
 #undef HAVE_SYS_DIR_H
 
-/* Define if you have the <sys/ndir.h> header file.  */
+/* Define if you have the <sys/ndir.h> header file, and it defines `DIR'. */
 #undef HAVE_SYS_NDIR_H
 
-/* Define if you have the <sys/rusage.h> header file.  */
+/* Define if you have the <sys/rusage.h> header file. */
 #undef HAVE_SYS_RUSAGE_H
 
-/* Define if you have the <sys/select.h> header file.  */
+/* Define if you have the <sys/select.h> header file. */
 #undef HAVE_SYS_SELECT_H
 
-/* Define if you have the <sys/time.h> header file.  */
+/* Define if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define if you have the <sys/time.h> header file. */
 #undef HAVE_SYS_TIME_H
 
-/* Define if you have the <unistd.h> header file.  */
+/* Define if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have the `uname' function. */
+#undef HAVE_UNAME
+
+/* Define if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
-/* Define if you have the dl library (-ldl).  */
-#undef HAVE_LIBDL
+/* Define if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
 
-/* Define if you have the dld library (-ldld).  */
-#undef HAVE_LIBDLD
+/* Define if you have the `vsprintf' function. */
+#undef HAVE_VSPRINTF
 
-/* Define if you have the dns library (-ldns).  */
-#undef HAVE_LIBDNS
+/* The size of a `int', as computed by sizeof. */
+#undef SIZEOF_INT
 
-/* Define if you have the nsl library (-lnsl).  */
-#undef HAVE_LIBNSL
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
 
-/* Define if you have the socket library (-lsocket).  */
-#undef HAVE_LIBSOCKET
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your processor stores words with the most significant byte first
+   (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+
+/* Define if on MINIX. */
+#undef _MINIX
+
+/* Define if the system does not provide POSIX.1 features except with this
+   defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define as `__inline' if that's what the C compiler calls it, or to nothing
+   if it is not supported. */
+#undef inline
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+#endif /* !_EGG_CONFIG_H */

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 576 - 202
configure


+ 35 - 21
configure.in

@@ -1,10 +1,11 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_REVISION($Revision $)
-AC_INIT(eggdrop.conf.dist)
+AC_INIT(src/eggdrop.h)
+AC_CONFIG_AUX_DIR(misc)
 AC_PREFIX_DEFAULT([\${HOME}/eggdrop])
 AC_CONFIG_HEADER(config.h)
 
 EGG_MSG_CONFIGURE_START
+EGG_SAVE_PARAMETERS
 
 # Setup build environment
 AC_PROG_CC
@@ -15,6 +16,9 @@ AC_AIX
 AC_ISC_POSIX
 AC_MINIX
 
+# Speedup compile
+EGG_CHECK_CCPIPE
+
 # Checks for programs
 AC_PROG_MAKE_SET
 AC_PROG_RANLIB
@@ -25,6 +29,9 @@ EGG_PROG_AWK
 EGG_PROG_BASENAME
 AC_CHECK_PROG(UNAME,uname,uname)
 
+# Should -O2 CFLAG be removed? 
+EGG_DISABLE_CC_OPTIMIZATION
+
 # Test the os and set the module linking settings
 EGG_CHECK_OS
 
@@ -36,52 +43,52 @@ AC_HEADER_DIRENT
 AC_HEADER_SYS_WAIT
 AC_CHECK_HEADERS(sys/time.h)
 AC_HEADER_TIME
-AC_CHECK_HEADERS(sys/select.h sys/rusage.h unistd.h dlfcn.h stdarg.h std_args.h strings.h)
+AC_CHECK_HEADERS(sys/select.h sys/rusage.h unistd.h dlfcn.h stdarg.h std_args.h strings.h limits.h)
 
 # Checks for typedefs, structures, and compiler characteristics
 AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_C_CONST
 AC_C_BIGENDIAN
 AC_C_INLINE
 AC_CHECK_SIZEOF(long, 0)
 AC_CHECK_SIZEOF(int, 0)
-AC_CHECK_SIZEOF(char, 0)
-AC_CHECK_SIZEOF(short int, 0)
 
 # Checks for library functions
-AC_CHECK_FUNCS(clock getrusage setpgid uname sigaction sigemptyset rename strcasecmp getdtablesize bzero random srandom dlopen dprintf snprintf vsnprintf)
+AC_CHECK_FUNCS(clock getrusage setpgid uname sigaction sigemptyset rename strcasecmp strncasecmp getdtablesize memset random srandom dlopen dprintf snprintf vsnprintf isascii inet_aton memcpy strftime fsync)
 EGG_CHECK_FUNC_VSPRINTF
 
 # Make sure we have stdc headers, since we can't compile without them
 EGG_HEADER_STDC
 
-# Checks for cygwin
-EGG_CYGWIN
-EGG_EXEEXT
+# Make sure we are using the correct result from a broken libsafe sscanf
+EGG_CHECK_LIBSAFE_SSCANF
 
-# Check how much space is left in filedb (informational purposes)
-EGG_CHECK_FILEDB_STRUCT
+# Checks for executable extension
+EGG_EXEEXT
 
-# Where is tcl?  Is it here?
-# ---------- begin robey's tcl thingies
-# (well, what used to be robey's tcl thingies...)
+# Where is Tcl?  Is it here?
+# ---------- begin robey's Tcl thingies
+# (well, what used to be robey's Tcl thingies...)
 
 # Latest tested Tcl version to recommend if Tcl isn't found
-tclrecommendver="8.2.2"
+tclrecommendver="8.3.3"
 
 # Site recommended to download Tcl from
-tclrecommendsite="ftp://ftp.scriptics.com/pub/tcl/tcl8_2/"
+tclrecommendsite="ftp://ftp.eggheads.org/pub/tcl/tcl8_3/"
 
 # Tcl library filename prefixes (also used for Tcl header dir on FreeBSD)
-tcllibnames="tcl tcl8.3 tcl83 tcl8.2 tcl82 tcl8.1 tcl81 \
+tcllibnames="tcl tcl8.4 tcl84 tcl8.3 tcl83 tcl8.2 tcl82 tcl8.1 tcl81 \
 	tcl8.0 tcl80 tcl7.6 tcl76 tcl7.5 tcl75 tcl7.4 tcl74 \
 	tcl7.3 tcl73 tcl7.2 tcl72 tcl7.1 tcl71 tcl7.0 tcl70"
 
 # Tcl library filename suffixes
-tcllibextensions=".so .so.1 .so.1.0 .so.1.2 .a"
+tcllibextensions=".so .so.1 .so.1.0 .so.1.2 .a .sl .dll"
 
 # Tcl library search paths
 tcllibpaths="/usr/local/lib /usr/local/pkgs/tcl/lib \
 	/usr/lib /lib /usr/i486-linuxaout/lib \
+	/beos/system/lib /sys/lib \
 	$HOME/lib $HOME/tcl/lib $HOME"
 
 # Tcl header filenames
@@ -89,7 +96,8 @@ tclheadernames="tcl.h"
 
 # Tcl header search paths
 tclheaderpaths="/usr/local/include /usr/local/pkgs/tcl/include \
-	/usr/include $HOME/include $HOME/tcl/include $HOME"
+	/usr/include /beos/system/include /beos/devel/include \
+       /sys/include $HOME/include $HOME/tcl/include $HOME"
 
 EGG_TCL_ARG_WITH
 EGG_TCL_ENV
@@ -99,20 +107,26 @@ EGG_TCL_FIND_LIBRARY
 EGG_TCL_FIND_HEADER
 EGG_TCL_CHECK_LIBRARY
 EGG_TCL_CHECK_HEADER
+EGG_TCL_DETECT_CHANGE
+
 EGG_TCL_CHECK_VERSION
 EGG_TCL_CHECK_PRE70
 EGG_TCL_CHECK_PRE75
 EGG_TCL_TESTLIBS
 EGG_TCL_CHECK_FREE
+EGG_TCL_ENABLE_THREADS
 EGG_TCL_CHECK_THREADS
 EGG_TCL_LIB_REQS
-# ---------- end of (what used to be) robey's tcl thingies
+EGG_TCL_LUSH
+# ---------- end of (what used to be) robey's Tcl thingies
 
 EGG_FUNC_DLOPEN
 
 EGG_SUBST_EGGVERSION
 EGG_SUBST_DEST
+EGG_SUBST_MOD_UPDIR
+EGG_CATCH_MAKEFILE_REBUILD
 
-AC_OUTPUT(Makefile doc/Makefile scripts/Makefile src/Makefile src/md5/Makefile src/mod/Makefile lush.h)
+AC_OUTPUT(Makefile doc/Makefile scripts/Makefile src/Makefile src/md5/Makefile src/compat/Makefile src/mod/Makefile)
 
 EGG_MSG_CONFIGURE_END

+ 0 - 3
lush.h.in

@@ -1,3 +0,0 @@
-/* ignore me but do not erase me.  i am a kludge. */
-
-#include "@TCLINC@/@TCLINCFN@"

+ 1308 - 0
misc/config.guess

@@ -0,0 +1,1308 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-10-05'
+
+# This file 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.
+#
+# 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 Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int dummy(){}" > $dummy.c ;
+	for c in cc gcc c89 ; do
+	  ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+	  if test $? = 0 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	rm -f $dummy.c $dummy.o $dummy.rel ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	# Determine the machine/vendor (is the vendor relevant).
+	case "${UNAME_MACHINE}" in
+	    amiga) machine=m68k-unknown ;;
+	    arm32) machine=arm-unknown ;;
+	    atari*) machine=m68k-atari ;;
+	    sun3*) machine=m68k-sun ;;
+	    mac68k) machine=m68k-apple ;;
+	    macppc) machine=powerpc-apple ;;
+	    hp3[0-9][05]) machine=m68k-hp ;;
+	    ibmrt|romp-ibm) machine=romp-ibm ;;
+	    sparc*) machine=`uname -p`-unknown ;;
+	    *) machine=${UNAME_MACHINE}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE}" in
+	    i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mipseb-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	cat <<EOF >$dummy.s
+	.data
+\$Lformat:
+	.byte 37,100,45,37,120,10,0	# "%d-%x\n"
+
+	.text
+	.globl main
+	.align 4
+	.ent main
+main:
+	.frame \$30,16,\$26,0
+	ldgp \$29,0(\$27)
+	.prologue 1
+	.long 0x47e03d80 # implver \$0
+	lda \$2,-1
+	.long 0x47e20c21 # amask \$2,\$1
+	lda \$16,\$Lformat
+	mov \$0,\$17
+	not \$1,\$18
+	jsr \$26,printf
+	ldgp \$29,0(\$26)
+	mov 0,\$16
+	jsr \$26,exit
+	.end main
+EOF
+	eval $set_cc_for_build
+	$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+	if test "$?" = 0 ; then
+		case `./$dummy` in
+			0-0)
+				UNAME_MACHINE="alpha"
+				;;
+			1-0)
+				UNAME_MACHINE="alphaev5"
+				;;
+			1-1)
+				UNAME_MACHINE="alphaev56"
+				;;
+			1-101)
+				UNAME_MACHINE="alphapca56"
+				;;
+			2-303)
+				UNAME_MACHINE="alphaev6"
+				;;
+			2-307)
+				UNAME_MACHINE="alphaev67"
+				;;
+			2-1307)
+				UNAME_MACHINE="alphaev68"
+				;;
+		esac
+	fi
+	rm -f $dummy.s $dummy
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD $dummy.c -o $dummy \
+	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && rm -f $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+		rm -f $dummy.c $dummy
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy`
+		    if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+		    rm -f $dummy.c $dummy
+		fi ;;
+	esac
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+	echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3D:*:*:*)
+	echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY-2:*:*:*)
+	echo cray2-cray-unicos
+        exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i386-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
+	  big)    echo mips-unknown-linux-gnu && exit 0 ;;
+	  little) echo mipsel-unknown-linux-gnu && exit 0 ;;
+	esac
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	ld_supported_targets=`cd /; ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;		
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-pc-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-pc-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+	$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	echo `uname -p`-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	if test "${UNAME_MACHINE}" = "x86pc"; then
+		UNAME_MACHINE=pc
+	fi
+	echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-[KW]:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+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`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:

+ 1413 - 0
misc/config.sub

@@ -0,0 +1,1413 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-10-05'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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.
+
+# 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.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| c4x | clipper \
+	| d10v | d30v | dsp16xx \
+	| fr30 \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| m32r | m68000 | m68k | m88k | mcore \
+	| mips16 | mips64 | mips64el | mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el | mips64vr4300 \
+	| mips64vr4300el | mips64vr5000 | mips64vr5000el \
+	| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
+	| mipsisa32 \
+	| mn10200 | mn10300 \
+	| ns16k | ns32k \
+	| openrisc \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| s390 | s390x \
+	| sh | sh[34] | sh[34]eb | shbe | shle \
+	| sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
+	| stormy16 | strongarm \
+	| tahoe | thumb | tic80 | tron \
+	| v850 \
+	| we32k \
+	| x86 | xscale \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alphapca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c54x-* \
+	| clipper-* | cray2-* | cydra-* \
+	| d10v-* | d30v-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| m32r-* \
+	| m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | mcore-* \
+	| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
+	| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
+	| mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| s390-* | s390x-* \
+	| sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclite-* \
+	| sparcv9-* | sparcv9b-* | stormy16-* | strongarm-* | sv1-* \
+	| t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
+	| v850-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	cray2)
+		basic_machine=cray2-cray
+		os=-unicos
+		;;
+	[cjt]90)
+		basic_machine=${basic_machine}-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mipsel*-linux*)
+		basic_machine=mipsel-unknown
+		os=-linux-gnu
+		;;
+	mips*-linux*)
+		basic_machine=mips-unknown
+		os=-linux-gnu
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+        pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2)
+		basic_machine=i686-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+	        ;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+	        ;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+	        ;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+	        ;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=t3e-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	windows32)
+		basic_machine=i386-pc
+		os=-windows32-msvcrt
+		;;
+	xmp)
+		basic_machine=xmp-cray
+		os=-unicos
+		;;
+        xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	mips)
+		if [ x$os = x-linux-gnu ]; then
+			basic_machine=mips-unknown
+		else
+			basic_machine=mips-mips
+		fi
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh3eb | sh4eb)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+        cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	c4x*)
+		basic_machine=c4x-none
+		os=-coff
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto*)
+		os=-nto-qnx
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-ns2 )
+	        os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+	        os=-mint
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	pdp10-*)
+		os=-tops20
+		;;
+        pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+        *-gould)
+		os=-sysv
+		;;
+        *-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+        *-sgi)
+		os=-irix
+		;;
+        *-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:

+ 1 - 1
install-sh → misc/install-sh

@@ -3,7 +3,7 @@
 # install - install a program, script, or datafile
 # This comes from X11R5 (mit/util/scripts/install.sh).
 #
-# $Id: install-sh,v 1.2 1999/12/15 02:32:57 guppy Exp $
+# $Id: install-sh,v 1.1 2000/03/05 23:22:48 fabian Exp $
 #
 # Copyright 1991 by the Massachusetts Institute of Technology
 #

+ 1 - 1
mkinstalldirs → misc/mkinstalldirs

@@ -4,7 +4,7 @@
 # Created: 1993-05-16
 # Public domain
 
-# $Id: mkinstalldirs,v 1.1 1999/10/27 07:54:39 arthur2 Exp $
+# $Id: mkinstalldirs,v 1.1 2000/03/05 23:22:48 fabian Exp $
 
 errstatus=0
 

+ 741 - 0
misc/modconfig

@@ -0,0 +1,741 @@
+#! /bin/sh
+#
+# modconfig
+#
+# Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+# Written by Fabian Knittel
+#
+# 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.
+
+# $Id: modconfig,v 1.9 2002/02/24 07:37:01 guppy Exp $
+
+
+mc_pn=`echo $0 | sed -e 's/^.*\///'`
+mc_top_srcdir=
+mc_srcdir=
+mc_bindir=.
+
+mc_flag_quiet=no
+mc_flag_onlynew=no
+
+
+#  Read options
+while true; do
+	case ${1} in
+	--top_srcdir=*)
+		mc_top_srcdir=`echo ${1} | sed -e 's/^--top_srcdir=//'`
+	;;
+	--top_srcdir)
+		shift
+		mc_top_srcdir=${1}
+	;;
+	--srcdir=*)
+		mc_srcdir=`echo ${1} | sed -e 's/^--srcdir=//'`
+	;;
+	--srcdir)
+		shift
+		mc_srcdir=${1}
+	;;
+	--bindir=*)
+		mc_bindir=`echo ${1} | sed -e 's/^--bindir=//'`
+	;;
+	--bindir)
+		shift
+		mc_bindir=${1}
+	;;
+	--quiet|-q)
+		mc_flag_quiet=yes
+	;;
+	--only-new|-n)
+		mc_flag_onlynew=yes
+	;;
+	--*)
+		echo "${mc_pn}: warning: unknown option \`${1}'." 2>&1
+	;;
+	*)
+		#  Non-option parameter. 
+		break
+	;;
+	esac
+
+	#  Break out of loop if there are no more arguments to process.
+	if shift; then
+		:
+	else
+		break;
+	fi
+done
+
+#  Find srcdir and top_srcdir
+if test "x${mc_srcdir}" = x; then
+	if test "x${mc_top_srcdir}" != x; then
+		mc_srcdir=${mc_top_srcdir}/src
+	else
+		echo "${mc_pn}: error: could not find src directory." 2>&1
+		exit 1
+	fi
+fi
+if test "x${mc_top_srcdir}" = x; then
+	if test "x${mc_srcdir}" != x; then
+		mc_top_srcdir=${mc_srcdir}/..
+	else
+		echo "${mc_pn}: error: could not find top src directory." 2>&1
+		exit 1
+	fi
+fi
+
+
+#
+#  Files
+#
+
+#  List of all selected modules (including the `.mod' at the end)
+mc_fmodules=${mc_bindir}/.modules
+
+#  List of all modules we have detected so far.
+mc_fknownmods=${mc_bindir}/.known_modules
+
+#  List of modules disabled by default
+mc_fdisabledmods=${mc_top_srcdir}/disabled_modules
+
+mc_mod_dir=${mc_srcdir}/mod
+
+mc_mod_bin_dir=${mc_bindir}/src/mod
+mc_fMakefile=${mc_mod_bin_dir}/Makefile
+
+mc_fstatic_h=${mc_mod_dir}/static.h
+
+
+#  File descriptor usage:
+#    1  Standard output
+#    2  Errors
+#
+#    6  Misc messages and warnings
+#    7  Goes to /dev/null
+exec 7>/dev/null
+if test "${mc_flag_quiet}" = yes; then
+	exec 6>&7
+else
+	exec 6>&1
+fi
+
+#  Detect flags needed to achieve 'echo -n' (originally from GNU autoconf) ...
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+	#  Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+	if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null
+	then
+		mc_n= mc_c='
+' mc_t='        '
+	else
+		mc_n=-n mc_c= mc_t=
+	fi
+else
+	mc_n= mc_c='\c' mc_t=
+fi
+
+#  This helps us call ourself.
+mc_self_call="$0 --srcdir=${mc_srcdir} --top_srcdir=${mc_topsrcdir}"
+
+#  Assign parameters
+mc_cmd=$1
+if test "x${mc_cmd}" != x; then
+	shift
+	mc_paras=$*
+fi
+
+case x${mc_cmd} in
+xhelp)
+#
+#  Display help
+#
+
+	cat 1>&6 <<EOF
+Usage: ${mc_pn} [OPTIONS] COMMAND
+
+Commands:
+    add                  Add a module to the list of active eggdrop modules.
+    del                  Remove a module from that list.
+    clear                Clear the list.
+    static.h             Create \`src/mod/static.h'.
+    Makefile             Create \`src/mod/Makefile'.
+    configure            Interactively select modules.
+    is-configured        Exits 0/1 depending on wether modules where
+                           configured or not.
+    update-depends       Check all module dependencies and add modules missing.
+    help                 Displays this information.
+    detect-modules       Find all available modules.
+    modules-still-exist  Check wether all known modules still exist.
+    eggautoconf          Recreate the configure scripts in every module dir.
+
+Options:
+    --top_srcdir=DIR     Top directory         (At least one of these two
+    --srcdir=DIR         Source directory       directories MUST be supplied.)
+    --bindir=DIR         Binary directory
+    --quiet [-q]         Quiet mode. Only show errors.
+
+Options specific to the \`configure' command:
+
+    --only-new [-n]      Only query new modules.
+EOF
+;;
+xis-configured)
+#
+#  Determine wether the modules were configured yet.
+#
+
+	if test -r "${mc_fmodules}"; then
+		exit 0
+	else
+		exit 1
+	fi
+;;
+xmodules-still-exist)
+#
+#  Check wether all known modules still exist.
+#
+
+	if ${mc_self_call} -q is-configured; then
+		mc_known_mods=`cat ${mc_fknownmods}`
+
+		echo ${mc_n} "checking for removed modules...${mc_c}" 1>&6
+		#  Check wether all known mods still exist
+		for mc_mod in ${mc_known_mods}; do
+			echo ${mc_n} ".${mc_c}" >&6
+			if test ! -d ${mc_mod_dir}/${mc_mod}; then
+				grep -v "^${mc_mod}$" ${mc_fknownmods} > ${mc_fknownmods}_new
+				mv ${mc_fknownmods}_new ${mc_fknownmods}
+			fi
+		done
+		echo " done." 1>&6
+	fi
+;;
+xdetect-modules)
+#
+#  Detect modules. Active modules will be added to the `.modules' file. The
+#  behaviour changes as soon as `.modules' already exists.
+#
+
+	echo ${mc_n} "detecting modules...${mc_c}" >&6
+
+	if ${mc_self_call} -q is-configured; then
+		mc_mods_configured=yes
+
+		mv ${mc_fmodules} ${mc_fmodules}_old
+
+		mc_fmodules_old=${mc_fmodules}
+		mc_fmodules=${mc_fmodules}_old
+	else
+		mc_mods_configured=no
+
+		mc_fmodules_old=
+	fi
+
+	mc_mods=`echo ${mc_srcdir}/mod/*.mod | sed -e 's/\.mod//g'`
+	if test "${mc_mods}" = "${mc_srcdir}/mod/*"; then
+		echo "${mc_pn}: error: no modules detected." >&2
+		exit 1
+	fi
+
+	#  Add them again.
+	mc_mods=`echo ${mc_mods} | sed -e 's/\.mod//g'`
+	for mc_mod in ${mc_mods}; do
+		mc_mod=`echo ${mc_mod} | sed -e 's/.*\///g'`
+		mc_new_mod_state=disabled
+		echo ${mc_n} ".${mc_c}" >&6
+
+		#  Do we have an existing configuration?
+		if (test "${mc_mods_configured}" = yes); then
+			#  Is the module active?
+			if (grep "^${mc_mod}.mod\$" ${mc_fmodules} 1>&7 2>&1)
+			then
+				mc_new_mod_state=enabled
+			else
+				#  Was it configured before?
+				if (grep "^${mc_mod}.mod\$" ${mc_fknownmods} 1>&7 2>&1); then
+					:
+				else
+					mc_new_mod_state=enabled
+				fi
+			fi
+		else
+			if (sed s/\ //g ${mc_fdisabledmods} 2>&1 | grep "^${mc_mod}\$" 1>&7 2>&1)
+			then
+				:
+			else
+				mc_new_mod_state=enabled
+			fi
+		fi
+		if test "${mc_new_mod_state}" = enabled; then
+			${mc_self_call} -q add ${mc_mod}
+		else
+			${mc_self_call} -q del ${mc_mod}
+		fi
+	done
+
+	if test "x${mc_fmodules_old}" != x; then
+		# mc_fmodules actually points to the .modules_old file.
+		rm -f ${mc_fmodules}
+		touch ${mc_fmodules_old}
+	fi
+
+	echo " done." >&6
+;;
+xMakefile)
+#
+#  Build `src/mod/Makefile'
+#
+
+	echo ${mc_n} "building ${mc_fMakefile}... ${mc_c}" 1>&6
+
+	#  Check for selected modules
+	if test -r ${mc_fmodules}; then
+		#  Convert newlines to spaces.
+		mc_sel_modules=`cat ${mc_fmodules} | \
+					awk '{ printf("%s ", $0); }'`
+	else
+		echo "${mc_pn}: error: no modules selected. You did not run \`make config' yet." 1>&2;
+		exit 1
+	fi
+
+	mc_mod_objs=`echo ${mc_sel_modules} | sed -e 's/.mod/.mod_o/g'`
+	mc_mod_libs=`echo ${mc_sel_modules} | sed -e 's/.mod/.mod_so/g'`
+
+	if test ! -f ${mc_fMakefile}; then
+		echo "failed." 1>&6
+		echo "${mc_pn}: error: make file template not found." 1>&2
+		exit 1
+	fi
+
+	#  The following sed expression modifies src/mod/Makefile to
+	#  hold the new module names.
+	if (cat "${mc_fMakefile}" | \
+	    sed -e "s/^\(mods =\).*$/\1 ${mc_sel_modules}/g"  \
+		-e "s/^\(mod_objs =\).*$/\1 ${mc_mod_objs}/g" \
+		-e "s/^\(mod_libs =\).*$/\1 ${mc_mod_libs}/g" \
+	    1> "${mc_fMakefile}_new"); then
+		mv "${mc_fMakefile}_new" "${mc_fMakefile}"
+	else
+		echo "failed." 1>&6
+		echo "${mc_pn}: sed failed to build ${mc_fMakefile}." 1>&2
+		exit 1
+	fi
+
+	echo "done." 1>&6
+;;
+xstatic.h)
+#
+#  Build `static.h'
+#
+
+	echo ${mc_n} "building static.h..." 1>&6
+
+	#  Check for selected modules
+	if test ! -r ${mc_fmodules}; then
+		echo " failed." 1>&6
+		echo "${mc_pn}: error: no modules selected. You did not run \`make config' yet." 1>&2;
+		exit 1
+	fi
+	mc_sel_modules=`cat ${mc_fmodules} | sed -e 's/.mod//g'`
+
+
+	#  Note:  All data is written to `src/mod/static.h' which is
+	#         later included into `src/main.c'.
+
+	#  Remove old static.h
+	rm -f ${mc_fstatic_h}
+
+	#  Header
+	cat 1>> ${mc_fstatic_h} << EOF
+/* src/mod/static.h -- header file for static compiles.
+ *
+ * NOTE: Do not edit directly. Instead, re-run \`make config'.
+ */
+
+#ifndef _EGG_MOD_STATIC_H
+#define _EGG_MOD_STATIC_H
+
+EOF
+
+	#  Create declarations for module _start functions
+	for mc_mod in ${mc_sel_modules}; do
+		echo ${mc_n} ".${mc_c}" 1>&6
+		echo "char *${mc_mod}_start();" 1>> ${mc_fstatic_h}
+	done
+	echo 1>> ${mc_fstatic_h}
+
+	#  The link_statics() function ...
+	echo "static void link_statics()" 1>> ${mc_fstatic_h}
+	echo "{" 1>> ${mc_fstatic_h}
+	for mc_mod in ${mc_sel_modules}; do
+		echo "  check_static(\"${mc_mod}\", ${mc_mod}_start);" 1>> ${mc_fstatic_h}
+	done
+	cat 1>> ${mc_fstatic_h} << EOF
+}
+
+#endif /* _EGG_MOD_STATIC_H */
+EOF
+
+	echo " done." 1>&6
+;;
+xdel)
+#
+#  Remove a module from the list
+#
+
+	if test "x${mc_paras}" = x; then
+		echo "${mc_pn}: error: no modules specified." 2>&1
+		exit 1
+	fi
+
+	mc_nfmodules="${mc_fmodules}_new"
+
+	#  Remove trailing `.mod'
+	mc_mods=`echo ${mc_paras} | sed -e 's/.mod//g'`
+	for mc_mod in ${mc_mods}; do
+		#  Remove any path information
+		mc_mod=`echo ${mc_mod} | sed -e 's/.*\///'`
+		echo "${mc_pn}: disabling eggdrop module: ${mc_mod}" 1>&6
+
+		#  Add module to the list of known modules.
+		if grep "^${mc_mod}.mod$" ${mc_fknownmods} 1>&7 2>&7; then
+			if test ! -d ${mc_mod_dir}/${mc_mod}.mod; then
+				grep -v "^${mc_mod}.mod$" ${mc_fknownmods} \
+					> ${mc_fknownmods}_new
+				mv ${mc_fknownmods}_new ${mc_fknownmods}
+			fi
+		else
+			if test ! -d ${mc_mod_dir}/${mc_mod}.mod; then
+				:
+			else
+				echo ${mc_mod}.mod 1>> ${mc_fknownmods}
+			fi
+		fi
+
+		# In case there are any active modules ...
+		if test -r ${mc_fmodules}; then
+			#  Remove module from list of active modules.
+			if grep -v "^${mc_mod}.mod$" ${mc_fmodules} \
+				1> ${mc_nfmodules}
+			then
+				:
+			else
+				echo "${mc_pn}: error: building new module file failed" 1>&2
+				echo "grepping for ${mc_mod}.mod in ${mc_fmodules} and writing to ${mc_nfmodules}"
+				kill -STOP $$
+				exit 1
+			fi
+			mv ${mc_nfmodules} ${mc_fmodules}
+		fi
+	done
+;;
+xadd)
+#
+#  Add a module to the list
+#
+
+	if test "x${mc_paras}" = x; then
+		echo "${mc_pn}: error: no modules specified." 2>&1
+		exit 1
+	fi
+
+	#  Remove trailing `.mod'
+	mc_mods=`echo ${mc_paras} | sed -e 's/.mod//g'`
+	for mc_mod in ${mc_mods}; do
+		#  Remove any path information
+		mc_mod=`echo ${mc_mod} | sed -e 's/.*\///'`
+
+		#  Add module to the list of known modules.
+		if grep "^${mc_mod}.mod$" ${mc_fknownmods} 1>&7 2>&7; then
+			if test ! -d ${mc_mod_dir}/${mc_mod}.mod; then
+				grep -v "^${mc_mod}.mod$" ${mc_fknownmods} \
+					> ${mc_fknownmods}_new
+				mv ${mc_fknownmods}_new ${mc_fknownmods}
+			fi
+		else
+			if test ! -d ${mc_mod_dir}/${mc_mod}.mod; then
+				:
+			else
+				echo ${mc_mod}.mod 1>> ${mc_fknownmods}
+			fi
+		fi
+
+		#  Add module to the list of active modules.
+		if grep "^${mc_mod}.mod$" ${mc_fmodules} 1>&7 2>&7; then
+			:
+		else
+			if test ! -d ${mc_mod_dir}/${mc_mod}.mod; then
+				echo "${mc_pn}: warning: module does not exist: \`${mc_mod}', ignoring." 1>&2
+			else
+				echo "${mc_pn}: enabling eggdrop module: ${mc_mod}" 1>&6
+
+				#  Add it to the file
+				echo ${mc_mod}.mod 1>> ${mc_fmodules}
+			fi
+		fi
+	done
+;;
+xclear)
+#
+#  Clear list of modules 
+#
+
+	echo "${mc_pn}: cleared list of eggdrop modules." 1>&6
+	rm -f ${mc_fmodules}
+	touch ${mc_fmodules}
+;;
+xupdate-depends)
+#
+#  Check the dependencies and add modules which are depended on, but
+#  aren't enabled.
+#
+
+	mc_all_depends=
+	mc_missing=
+
+	echo ${mc_n} "calculating dependencies...${mc_c}" 1>&6
+
+	#  Check for selected modules
+	if test ! -r ${mc_fmodules}; then
+		echo " failed." 1>&6
+		echo "${mc_pn}: error: no modules selected. You did not run configure yet." 1>&2
+		exit 1
+	fi
+	mc_sel_modules=`cat ${mc_fmodules}`
+
+	mc_new_mods="${mc_sel_modules}"
+	while (test "x${mc_new_mods}" != x); do
+		mc_mod_list="${mc_new_mods}"
+		mc_new_mods=
+
+		#  Go through every module in the list
+		for mc_mod in ${mc_mod_list}; do
+			echo ${mc_n} ".${mc_c}" 1>&6
+
+			#  We have an info file, don't we?
+			if (test ! -f ${mc_mod_dir}/${mc_mod}/modinfo); then
+				continue
+			fi
+
+			#  Figure out the module's dependencies
+			mc_mod_depends=`grep "^DEPENDS:" ${mc_mod_dir}/${mc_mod}/modinfo | sed -e 's/^DEPENDS://'`
+
+			#  Check wether the dependencies are fulfilled
+			for mc_m_depend in ${mc_mod_depends}; do
+				if (echo ${mc_sel_modules} | \
+					grep " ${mc_m_depend}" 1>&7 2>&7) || \
+				    (echo ${mc_sel_modules} | \
+					grep "^${mc_m_depend}" 1>&7 2>&7)
+				then
+					:
+				else
+					#  Does the module actually exist?
+					if test ! -d ${mc_mod_dir}/${mc_m_depend}.mod
+					then
+						mc_missing="${mc_missing} ${mc_m_depend}"
+						continue
+					fi
+
+					#  This one is missing. Add it to the
+					#  list.
+					mc_all_depends="${mc_all_depends} ${mc_m_depend}"
+					mc_sel_modules="${mc_sel_modules} ${mc_m_depend}"
+
+					#  Add to list of modules to check in
+					#  next dependency cycle.
+					mc_new_mods="${mc_new_mods} ${mc_m_depend}.mod"
+				fi
+			done
+		done
+	done
+	echo " done." 1>&6
+
+	#  Warn about missing modules.
+	if test "x${mc_missing}" != x; then
+		cat 1>&2 <<EOF
+${mc_pn}: warning:
+
+   The following modules were not found but are needed:
+
+      `echo ${mc_missing} | sed -e 's/ /, /g'`
+
+EOF
+		echo ${mc_n} "Press enter to continue... ${mc_c}"
+		read mc_ask_response
+	fi
+
+	if test "x${mc_all_depends}" != x; then
+		echo ${mc_n} "adding modules needed to match dependencies... ${mc_c}" 1>&6
+		echo ${mc_all_depends} | sed -e 's/ /, /g' 1>&6
+
+		#  Add the modules
+		${mc_self_call} -q add ${mc_all_depends}
+
+		#  Update the makefile
+		${mc_self_call} -q Makefile
+	fi
+;;
+xconfigure)
+#
+#  Interactive module selection
+#
+
+	cat 1>&6 <<EOF
+
+            -*-    Eggdrop Interactive Module Selection    -*-
+
+EOF
+
+	#  Check for selected modules
+	if test ! -r ${mc_fmodules}; then
+		echo "${mc_pn}: error: no modules selected. You did not run configure yet." 1>&2
+		exit 1
+	fi
+
+	#  Read current list
+	mc_sel_modules=`cat ${mc_fmodules}`
+
+	#  Detect available modules
+	mc_mods=`echo ${mc_mod_dir}/*.mod`
+
+	#  Error out if we have no available modules
+	if test "${mc_mods}" = "echo ${mc_mod_dir}/*.mod"; then
+		echo "${mc_pn}: error: no modules found." 1>&2
+		exit 1
+	fi
+
+	#  Loop through each available module
+	for mc_mod in ${mc_mods}; do
+		#  Remove directory information from name
+		mc_mod=`echo ${mc_mod} | sed -e 's/.*\///'`
+
+		#  Only ask for new modules?
+		if test "${mc_flag_onlynew}" = yes; then
+			#  Did we already query for that module?
+			if grep "^${mc_mod}$" ${mc_fknownmods} 1>&7 2>&7; then
+				continue
+			fi
+		fi
+
+		#  Remove .mod ending
+		mc_modname=`echo ${mc_mod} | sed -e 's/.mod//g'`
+
+		#  Note: We need to make sure that we only catch module names
+		#        that match _exactly_. e.g. don't mix bseen and seen.
+		if (echo ${mc_sel_modules} | grep " ${mc_mod}" 1>&7 2>&7) ||
+		    (echo ${mc_sel_modules} | grep "^${mc_mod}" 1>&7 2>&7)
+
+		then
+			#  The module is selected.
+			mc_mstate="enabled"
+			mc_mdisp="(E)nable / (d)isable  [E/d]"
+		else
+			#  The module is NOT selected.
+			mc_mstate="disabled"
+			mc_mdisp="(e)nable / (D)isable  [e/D]"
+		fi
+
+		#  Display description
+		if test -r ${mc_mod_dir}/${mc_mod}/modinfo; then
+			echo "" 1>&6
+			grep "^DESC:" ${mc_mod_dir}/${mc_mod}/modinfo | \
+				sed -e 's/^DESC:/   /' 1>&6
+			echo "" 1>&6
+		fi
+
+		while true; do
+			echo ${mc_n} "\`${mc_modname}' is ${mc_mstate}, ${mc_mdisp} ${mc_c}" 1>&6
+			read mc_ask_response;
+
+			if (test "${mc_ask_response}" = D); then
+				mc_ask_response=d;
+			fi
+			if (test "${mc_ask_response}" = E); then
+				mc_ask_response=e;
+			fi
+
+			#  If the user just presses [return] or
+			#  if the selected state matches the old state,
+			#  then we change nothing.
+			if test "x${mc_ask_response}" = x || \
+			    (test "${mc_ask_response}" = d && \
+			     test "${mc_mstate}" = disabled) || \
+			    (test "${mc_ask_response}" = e && \
+			     test "${mc_mstate}" = enabled); then
+				echo "Changing nothing." 1>&6
+				break;
+			fi
+			if (test "${mc_ask_response}" = e); then
+				#  Add it to the list.
+				mc_sel_modules="${mc_sel_modules} ${mc_mod}"
+				echo "Enabled module ${mc_modname}." 1>&6
+				break;
+			fi
+			if (test "${mc_ask_response}" = d); then
+				#  Remove module from list.
+				mc_sel_modules=`echo ${mc_sel_modules} | sed -e "s/ ${mc_mod}//g" -e "s/^${mc_mod}//g"`
+				echo "Disabled module ${mc_modname}." 1>&6
+				break;
+			fi
+		done
+		echo "" 1>&6
+	done
+
+	echo ${mc_n} "recreating list of active modules... ${mc_c}" 1>&6
+	${mc_self_call} -q clear
+	if (${mc_self_call} -q add ${mc_sel_modules}); then
+		echo "done." 1>&6
+	else
+		echo "failed!" 1>&6
+		exit 1
+	fi
+;;
+xeggautoconf)
+#
+#  Recreate the eggdrop specific configure scripts for every module.
+#
+
+	#  Detect available modules
+	mc_mods=`echo ${mc_mod_dir}/*.mod`
+
+	#  Error out if we have no available modules
+	if test "${mc_mods}" = "echo ${mc_mod_dir}/*.mod"; then
+		echo "${mc_pn}: error: no modules found." 1>&2
+		exit 1
+	fi
+
+	#  Loop through each available module
+	for mc_modd in ${mc_mods}; do
+		#  Skip modules without their own configure script.
+		if test ! -r "${mc_modd}/configure.in"; then
+			continue
+		fi
+
+		#  Remove directory information from name
+		mc_mod=`echo ${mc_modd} | sed -e 's/.*\///'`
+		echo "creating configure for module \`${mc_mod}'."
+		(cd ${mc_modd} && ../eggautoconf)
+	done
+;;
+*)
+	if test "x${mc_cmd}" = x; then
+		echo "${mc_pn}: error: no command supplied." 1>&2
+	else
+		echo "${mc_pn}: error: ${mc_cmd}: unknown command." 1>&2
+	fi
+	${mc_self_call} help
+;;
+esac
+
+exit 0

+ 156 - 74
src/Makefile.in

@@ -1,8 +1,10 @@
 # Makefile for src/
-# $Id: Makefile.in,v 1.8 1999/12/15 02:32:57 guppy Exp $
+# $Id: Makefile.in,v 1.15 2000/11/23 03:56:40 guppy Exp $
 
-SHELL = /bin/sh
+SHELL = @SHELL@
 top_srcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
 
 @SET_MAKE@
 INSTALL = @INSTALL@
@@ -10,25 +12,32 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 
-OBJS = botcmd.o botmsg.o botnet.o chanprog.o cmds.o dcc.o \
-dccutil.o flags.o language.o main.o mem.o misc.o \
-modules.o net.o rfc1459.o tcl.o tcldcc.o tclhash.o \
-tclmisc.o tcluser.o userent.o userrec.o users.o md5/md5c.o
+CC = @CC@
+LD = @CC@
+STRIP = @STRIP@
+CFLAGS = @CFLAGS@ -I.. -I$(top_srcdir) @DEFS@ $(CFLGS)
+CPPFLAGS = @CPPFLAGS@
 
-MAKE_MD5 = $(MAKE) 'MAKE=$(MAKE)' 'CC=$(CC)' 'LD=$(LD)' \
-'STRIP=$(STRIP)' 'CFLAGS=$(CFLAGS)' 'CPPFLAGS=$(CPPFLAGS)'
+eggdrop_objs = bg.o botcmd.o botmsg.o botnet.o chanprog.o cmds.o dcc.o \
+dccutil.o dns.o flags.o language.o main.o mem.o misc.o misc_file.o \
+modules.o net.o rfc1459.o tcl.o tcldcc.o tclhash.o tclmisc.o \
+tcluser.o userent.o userrec.o users.o
+
+MAKE_GENERIC = $(MAKE) 'MAKE=$(MAKE)' 'CC=$(CC)' 'LD=$(LD)' \
+'STRIP=$(STRIP)' 'CFLGS=$(CFLGS)'
 
 doofus:
 	@echo ""
 	@echo "Let's try this from the right directory..."
 	@echo ""
-	@cd $(top_srcdir); $(MAKE)
+	@cd .. && $(MAKE)
 
-../$(EGGEXEC): $(OBJS) $(XREQS)
+../$(EGGEXEC): build_msg $(eggdrop_objs) $(XREQS) compile_md5 compatability
 	@echo ""
 	@echo "Linking eggdrop... $(EGGBUILD)"
 	@echo ""
-	$(LD) -o ../$(EGGEXEC) $(OBJS) $(MODOBJS) $(XLIBS)
+	@touch mod/mod.xlibs
+	$(LD) -o ../$(EGGEXEC) $(eggdrop_objs) $(MODOBJS) $(XLIBS) md5/md5c.o compat/*.o `cat mod/mod.xlibs`
 	$(STRIP) ../$(EGGEXEC)
 	@echo "Successful compile: $(EGGEXEC)"
 	@echo ""
@@ -36,25 +45,27 @@ doofus:
 $(EGGEXEC): ../$(EGGEXEC)
 
 depend:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -MM *.c > .depend
+	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/*.c > .depend
 
 clean:
 	@rm -f .depend *.o *.a *~
 
-botcmd.o:
-	@echo "(This will take a while. Go make a pizza or something.)"
-	$(CC) $(CFLAGS) $(CPPFLAGS) -c botcmd.c
+build_msg:
+	@echo "(This may take a while.  Go get some runts.)"
 
 main.o:
 	$(CC) $(CFLAGS) $(CPPFLAGS) \
 '-DCCFLAGS="$(CC) $(CFLAGS) $(CPPFLAGS)"' \
 '-DLDFLAGS="$(LD)"' \
-'-DSTRIPFLAGS="$(STRIP)"' -c main.c
+'-DSTRIPFLAGS="$(STRIP)"' -c $(srcdir)/main.c
 
-md5/md5c.o:
-	@cd md5; $(MAKE_MD5) md5
+compatability:
+	@cd compat && $(MAKE_GENERIC) compat
 	@echo "---------- Yeah! that's the compiling, now the linking! ----------"
 
+compile_md5:
+	@cd md5 && $(MAKE_GENERIC) md5
+
 libtcle.a: $(TCLLIB)/lib$(TCLLIBFN)
 	@echo "[ Fixing lib$(TCLLIBFN) -> libtcle.a ]"
 	cp $(TCLLIB)/lib$(TCLLIBFN) libtcle.a
@@ -73,60 +84,131 @@ eggdrop.h:
 	$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
 
 #safety hash
-botcmd.o: botcmd.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h tandem.h modules.h \
- mod/modvals.h
-botmsg.o: botmsg.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h tandem.h
-botnet.o: botnet.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h tandem.h
-chanprog.o: chanprog.c main.h lang.h eggdrop.h flags.h proto.h \
- ../lush.h cmdt.h tclegg.h tclhash.h chan.h users.h modules.h \
- mod/modvals.h
-cmds.o: cmds.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h tandem.h modules.h \
- mod/modvals.h
-dcc.o: dcc.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h cmdt.h \
- tclegg.h tclhash.h chan.h users.h modules.h mod/modvals.h tandem.h \
- md5/global.h md5/md5.h
-dccutil.o: dccutil.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h modules.h mod/modvals.h \
- tandem.h
-flags.o: flags.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h
-language.o: language.c main.h lang.h eggdrop.h flags.h proto.h \
- ../lush.h cmdt.h tclegg.h tclhash.h chan.h users.h
-main.o: main.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h modules.h mod/modvals.h \
- tandem.h patch.h
-match.o: match.c
-mem.o: mem.c mod/modvals.h
-misc.o: misc.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h
-modules.o: modules.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h modules.h mod/modvals.h \
- tandem.h
-net.o: net.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h cmdt.h \
- tclegg.h tclhash.h chan.h users.h
-rfc1459.o: rfc1459.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h
-tcl.o: tcl.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h cmdt.h \
- tclegg.h tclhash.h chan.h users.h
-tcldcc.o: tcldcc.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h tandem.h modules.h \
+bg.o: ./bg.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
+ ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
+ compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
+ bg.h
+botcmd.o: ./botcmd.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h tandem.h modules.h mod/modvals.h
+botmsg.o: ./botmsg.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h tandem.h
+botnet.o: ./botnet.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h tandem.h
+chanprog.o: ./chanprog.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h modules.h mod/modvals.h
+cmds.o: ./cmds.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
+ ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
+ compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
+ tandem.h modules.h mod/modvals.h
+dcc.o: ./dcc.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
+ ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
+ compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
+ modules.h mod/modvals.h tandem.h md5/md5.h
+dccutil.o: ./dccutil.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h modules.h mod/modvals.h tandem.h
+dns.o: ./dns.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
+ ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
+ compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
+ dns.h
+flags.o: ./flags.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
+ ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
+ compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h
+language.o: ./language.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h
+main.o: ./main.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
+ ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
+ compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
+ modules.h mod/modvals.h tandem.h bg.h patch.h
+match.o: ./match.c
+mem.o: ./mem.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
+ ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
+ compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
  mod/modvals.h
-tclhash.o: tclhash.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h match.c
-tclmisc.o: tclmisc.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h modules.h mod/modvals.h \
- tandem.h
-tcluser.o: tcluser.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h tandem.h
-userent.o: userent.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h
-userrec.o: userrec.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h modules.h mod/modvals.h \
- tandem.h
-users.o: users.c main.h lang.h eggdrop.h flags.h proto.h ../lush.h \
- cmdt.h tclegg.h tclhash.h chan.h users.h modules.h mod/modvals.h \
- tandem.h
+misc.o: ./misc.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
+ ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
+ compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
+ stat.h
+misc_file.o: ./misc_file.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h stat.h
+modules.o: ./modules.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h modules.h mod/modvals.h tandem.h
+net.o: ./net.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
+ ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
+ compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h
+rfc1459.o: ./rfc1459.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h
+tcl.o: ./tcl.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
+ ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
+ compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h
+tcldcc.o: ./tcldcc.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h tandem.h modules.h mod/modvals.h
+tclhash.o: ./tclhash.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h match.c
+tclmisc.o: ./tclmisc.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h modules.h mod/modvals.h tandem.h md5/md5.h
+tcluser.o: ./tcluser.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h tandem.h
+userent.o: ./userent.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h
+userrec.o: ./userrec.c main.h ../config.h lang.h eggdrop.h flags.h \
+ proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
+ users.h compat/compat.h compat/inet_aton.h ../src/main.h \
+ compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
+ compat/strftime.h modules.h mod/modvals.h tandem.h
+users.o: ./users.c main.h ../config.h lang.h eggdrop.h flags.h proto.h \
+ ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
+ compat/compat.h compat/inet_aton.h ../src/main.h compat/snprintf.h \
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
+ modules.h mod/modvals.h tandem.h

+ 258 - 0
src/bg.c

@@ -0,0 +1,258 @@
+/*
+ * bg.c -- handles:
+ *   moving the process to the background, i.e. forking, while keeping threads
+ *   happy.
+ *
+ * $Id: bg.c,v 1.5 2002/01/02 03:46:35 guppy Exp $
+ */
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 "main.h"
+#include <signal.h>
+#include "bg.h"
+
+#ifdef HAVE_TCL_THREADS
+#  define SUPPORT_THREADS
+#endif
+
+extern char	pid_file[];
+
+#ifdef SUPPORT_THREADS
+
+/* When threads are started during eggdrop's init phase, we can't simply
+ * fork() later on, because that only copies the VM space over and
+ * doesn't actually duplicate the threads.
+ *
+ * To work around this, we fork() very early and let the parent process
+ * wait in an event loop. As soon as the init phase is completed and we
+ * would normally move to the background, the child process simply
+ * messages it's parent that it may now quit. This allows us to control
+ * the terminal long enough to, e.g. properly feed error messages to
+ * cron scripts and let the user abort the loading process by hitting
+ * CTRL+C.
+ *
+ *
+ * [ Parent process                  ] [ Child process                   ]
+ *
+ *   main()
+ *     ...
+ *     bg_prepare_split()
+ *       fork()                              - created -
+ *       waiting in event loop.            continuing execution in main()
+ *                                         ...
+ *                                         completed init.
+ *                                         bg_do_detach()
+ *                                           message parent new PID file-
+ *                                            name.
+ *       receives new PID filename
+ *         message.
+ *                                           message parent to quit.
+ *       receives quit message.            continues to main loop.
+ *       writes PID to file.               ...
+ *       exits.
+ */
+
+/* Format of messages sent from the newly forked process to the
+   original process, connected to the terminal. */
+typedef struct {
+	enum {
+		BG_COMM_QUIT,		/* Quit original process. Write
+					   PID file, etc. i.e. detach.	 */
+		BG_COMM_ABORT,		/* Quit original process.	 */
+		BG_COMM_TRANSFERPF	/* Sending pid_file.		 */
+	} comm_type;
+	union {
+		struct {		/* Data for BG_COMM_TRANSFERPF.	 */
+			int	len;	/* Length of the file name.	 */
+		} transferpf;
+	} comm_data;
+} bg_comm_t;
+
+typedef enum {
+	BG_NONE = 0,			/* No forking has taken place
+					   yet.				 */
+	BG_SPLIT,			/* I'm the newly forked process. */
+	BG_PARENT			/* I'm the original process.	 */
+} bg_state_t;
+
+typedef struct {
+	int		comm_recv;	/* Receives messages from the
+					   child process.		 */
+	int		comm_send;	/* Sends messages to the parent
+					   process.			 */
+	bg_state_t	state;		/* Current state, see above
+					   enum descriptions.		 */
+	pid_t		child_pid;	/* PID of split process.	 */
+} bg_t;
+
+static bg_t	bg = { 0 };
+
+#endif /* SUPPORT_THREADS */
+
+
+/* Do everything we normally do after we have split off a new
+ * process to the background. This includes writing a PID file
+ * and informing the user of the split.
+ */
+static void bg_do_detach(pid_t p)
+{
+  FILE	*fp;
+
+  /* Need to attempt to write pid now, not later. */
+  unlink(pid_file);
+  fp = fopen(pid_file, "w");
+  if (fp != NULL) {
+    fprintf(fp, "%u\n", p);
+    if (fflush(fp)) {
+      /* Kill bot incase a botchk is run from crond. */
+      printf(EGG_NOWRITE, pid_file);
+      printf("  Try freeing some disk space\n");
+      fclose(fp);
+      unlink(pid_file);
+      exit(1);
+    }
+    fclose(fp);
+  } else
+    printf(EGG_NOWRITE, pid_file);
+  printf("Launched into the background  (pid: %d)\n\n", p);
+#if HAVE_SETPGID
+  setpgid(p, p);
+#endif
+  exit(0);
+}
+
+void bg_prepare_split(void)
+{
+#ifdef SUPPORT_THREADS
+  /* Create a pipe between parent and split process, fork to create a
+     parent and a split process and wait for messages on the pipe. */
+  pid_t		p;
+  bg_comm_t	message;
+
+  {
+    int		comm_pair[2];
+
+    if (pipe(comm_pair) < 0)
+      fatal("CANNOT OPEN PIPE.", 0);
+
+    bg.comm_recv = comm_pair[0];
+    bg.comm_send = comm_pair[1];
+  }
+
+  p = fork();
+  if (p == -1)
+    fatal("CANNOT FORK PROCESS.", 0);
+  if (p == 0) {
+    bg.state = BG_SPLIT;
+    return;
+  } else {
+    bg.child_pid = p;
+    bg.state = BG_PARENT;
+  }
+
+  while (read(bg.comm_recv, &message, sizeof(message)) > 0) {
+    switch (message.comm_type) {
+    case BG_COMM_QUIT:
+      bg_do_detach(p);
+      break;
+    case BG_COMM_ABORT:
+      exit(1);
+      break;
+    case BG_COMM_TRANSFERPF:
+      /* Now transferring file from split process.
+       */
+      if (message.comm_data.transferpf.len >= 40)
+	message.comm_data.transferpf.len = 40 - 1;
+      /* Next message contains data. */
+      if (read(bg.comm_recv, pid_file, message.comm_data.transferpf.len) <= 0)
+	goto error;
+      pid_file[message.comm_data.transferpf.len] = 0;
+      break;
+    }
+  }
+
+error:
+  /* We only reach this point in case of an error.
+   */
+  fatal("COMMUNICATION THROUGH PIPE BROKE.", 0);
+#endif
+}
+
+#ifdef SUPPORT_THREADS
+/* Transfer contents of pid_file to parent process. This is necessary,
+ * as the pid_file[] buffer has changed in this fork by now, but the
+ * parent needs an up-to-date version.
+ */
+static void bg_send_pidfile(void)
+{
+  bg_comm_t	message;
+
+  message.comm_type = BG_COMM_TRANSFERPF;
+  message.comm_data.transferpf.len = strlen(pid_file);
+
+  /* Send type message. */
+  if (write(bg.comm_send, &message, sizeof(message)) < 0)
+    goto error;
+  /* Send data. */
+  if (write(bg.comm_send, pid_file, message.comm_data.transferpf.len) < 0)
+    goto error;
+  return;
+error:
+  fatal("COMMUNICATION THROUGH PIPE BROKE.", 0);
+}
+#endif
+
+void bg_send_quit(bg_quit_t q)
+{
+#ifdef SUPPORT_THREADS
+  if (bg.state == BG_PARENT) {
+    kill(bg.child_pid, SIGKILL);
+  } else if (bg.state == BG_SPLIT) {
+    bg_comm_t	message;
+
+    if (q == BG_QUIT) {
+      bg_send_pidfile();
+      message.comm_type = BG_COMM_QUIT;
+    } else
+      message.comm_type = BG_COMM_ABORT;
+    /* Send message. */
+    if (write(bg.comm_send, &message, sizeof(message)) < 0)
+      fatal("COMMUNICATION THROUGH PIPE BROKE.", 0);
+  }
+#endif
+}
+
+void bg_do_split(void)
+{
+#ifdef SUPPORT_THREADS
+  /* Tell our parent process to go away now, as we don't need it
+     anymore. */
+  bg_send_quit(BG_QUIT);
+#else
+  /* Split off a new process.
+   */
+  int	xx = fork();
+
+  if (xx == -1)
+    fatal("CANNOT FORK PROCESS.", 0);
+  if (xx != 0)
+    bg_do_detach(xx);
+#endif
+}

+ 36 - 0
src/bg.h

@@ -0,0 +1,36 @@
+/*
+ * bg.h
+ *
+ * $Id: bg.h,v 1.3 2002/01/02 03:46:35 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_BG_H
+#define _EGG_BG_H
+
+typedef enum {
+	BG_QUIT = 1,
+	BG_ABORT
+} bg_quit_t;
+
+void bg_prepare_split(void);
+void bg_send_quit(bg_quit_t q);
+void bg_do_split(void);
+
+#endif			/* _EGG_BG_H */

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 193 - 174
src/botcmd.c


+ 66 - 79
src/botmsg.c

@@ -1,26 +1,26 @@
-/* 
+/*
  * botmsg.c -- handles:
  *   formatting of messages to be sent on the botnet
  *   sending differnet messages to different versioned bots
- * 
+ *
  * by Darrin Smith (beldin@light.iinet.net.au)
- * 
- * $Id: botmsg.c,v 1.13 2000/01/08 21:23:13 per Exp $
+ *
+ * $Id: botmsg.c,v 1.25 2002/01/02 03:46:35 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -29,42 +29,42 @@
 #include "main.h"
 #include "tandem.h"
 
-extern struct dcc_t *dcc;
-extern int dcc_total, tands;
-extern char botnetnick[];
-extern party_t *party;
-extern Tcl_Interp *interp;
-extern struct userrec *userlist;
+extern struct dcc_t	*dcc;
+extern int		 dcc_total, tands;
+extern char		 botnetnick[];
+extern party_t		*party;
+extern Tcl_Interp	*interp;
+extern struct userrec	*userlist;
+
+static char	OBUF[1024];
 
-static char OBUF[1024];
 
 #ifndef NO_OLD_BOTNET
-/* ditto for tandem bots */
+/* Ditto for tandem bots
+ */
 void tandout_but EGG_VARARGS_DEF(int, arg1)
 {
-  int i, x, l;
+  int i, x, len;
   char *format;
   char s[601];
-
   va_list va;
+
   x = EGG_VARARGS_START(int, arg1, va);
   format = va_arg(va, char *);
-
-#ifdef HAVE_VSNPRINTF
-  if ((l = vsnprintf(s, 511, format, va)) < 0)
-    s[l = 511] = 0;
-#else
-  l = vsprintf(s, format, va);
-#endif
+  egg_vsnprintf(s, 511, format, va);
   va_end(va);
+  s[sizeof(s)-1] = 0;
+
+  len = strlen(s);
+
   for (i = 0; i < dcc_total; i++)
     if ((dcc[i].type == &DCC_BOT) && (i != x) &&
-	(b_numver(i) < NEAT_BOTNET))
-      tputs(dcc[i].sock, s, l);
+        (b_numver(i) < NEAT_BOTNET))
+      tputs(dcc[i].sock, s, len);
 }
 #endif
 
-/* thank you ircu :) */
+/* Thank you ircu :) */
 static char tobase64array[64] =
 {
   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
@@ -142,33 +142,29 @@ int simple_sprintf EGG_VARARGS_DEF(char *,arg1)
 {
   char *buf, *format, *s;
   int c = 0, i;
-
   va_list va;
+
   buf = EGG_VARARGS_START(char *, arg1, va);
   format = va_arg(va, char *);
 
-  while (*format && (c < 1023)) {
+  while (*format && c < 1023) {
     if (*format == '%') {
       format++;
       switch (*format) {
       case 's':
 	s = va_arg(va, char *);
-
 	break;
       case 'd':
       case 'i':
 	i = va_arg(va, int);
-
 	s = int_to_base10(i);
 	break;
       case 'D':
 	i = va_arg(va, int);
-
 	s = int_to_base64((unsigned int) i);
 	break;
       case 'u':
 	i = va_arg(va, unsigned int);
-
         s = unsigned_int_to_base10(i);
 	break;
       case '%':
@@ -176,15 +172,14 @@ int simple_sprintf EGG_VARARGS_DEF(char *,arg1)
 	continue;
       case 'c':
 	buf[c++] = (char) va_arg(va, int);
-
 	format++;
 	continue;
       default:
 	continue;
       }
       if (s)
-      while (*s && (c < 1023))
-        buf[c++] = *s++;
+	while (*s && c < 1023)
+	  buf[c++] = *s++;
       format++;
     } else
       buf[c++] = *format++;
@@ -194,7 +189,8 @@ int simple_sprintf EGG_VARARGS_DEF(char *,arg1)
   return c;
 }
 
-/* ditto for tandem bots */
+/* Ditto for tandem bots
+ */
 void send_tand_but(int x, char *buf, int len)
 {
   int i, iso = 0;
@@ -296,21 +292,17 @@ void botnet_send_priv EGG_VARARGS_DEF(int, arg1)
   int idx, l;
   char *from, *to, *tobot, *format;
   char tbuf[1024];
-
   va_list va;
+
   idx = EGG_VARARGS_START(int, arg1, va);
   from = va_arg(va, char *);
   to = va_arg(va, char *);
   tobot = va_arg(va, char *);
   format = va_arg(va, char *);
-
-#ifdef HAVE_VSNPRINTF
-  if (vsnprintf(tbuf, 450, format, va) < 0)
-    tbuf[450] = 0;
-#else
-  vsprintf(tbuf, format, va);
-#endif
+  egg_vsnprintf(tbuf, 450, format, va);
   va_end(va);
+  tbuf[sizeof(tbuf)-1] = 0;
+
   if (tobot) {
 #ifndef NO_OLD_BOTNET
     if (b_numver(idx) < NEAT_BOTNET)
@@ -383,8 +375,6 @@ void botnet_send_unlinked(int idx, char *bot, char *args)
 {
   int l;
 
-  Context;
-
   if (tands > 0) {
     l = simple_sprintf(OBUF, "un %s %s\n", bot, args ? args : "");
     send_tand_but(idx, OBUF, l);
@@ -562,7 +552,6 @@ void botnet_send_idle(int idx, char *bot, int sock, int idle, char *away)
 {
   int l;
 
-  Context;
   if (tands > 0) {
     l = simple_sprintf(OBUF, "i %s %D %D %s\n", bot, sock, idle,
 		       away ? away : "");
@@ -651,19 +640,18 @@ void botnet_send_join_party(int idx, int linking, int useridx, int oldchan)
 {
   int l;
 
-  Context;
   if (tands > 0) {
     l = simple_sprintf(OBUF, "j %s%s %s %D %c%D %s\n", linking ? "!" : "",
 		       party[useridx].bot, party[useridx].nick,
 		       party[useridx].chan, party[useridx].flag,
 		       party[useridx].sock,
-		       safe_str(party[useridx].from));
+		       party[useridx].from ? party[useridx].from : "");
     send_tand_but(idx, OBUF, -l);
 #ifndef NO_OLD_BOTNET
     tandout_but(idx, "join %s %s %d %c%d %s\n", party[useridx].bot,
 		party[useridx].nick, party[useridx].chan,
 		party[useridx].flag, party[useridx].sock,
-		safe_str(party[useridx].from));
+		party[useridx].from ? party[useridx].from : "");
     if ((idx < 0) || (!linking && (b_numver(idx) >= NEAT_BOTNET))) {
       tandout_but(idx, "chan %s %d %s %s %s.\n",
 		  party[useridx].bot, party[useridx].chan,
@@ -761,7 +749,7 @@ void botnet_send_nkch_part(int butidx, int useridx, char *oldnick)
     tandout_but(butidx, "join %s %s %d %c%d %s\n", party[useridx].bot,
 		party[useridx].nick, party[useridx].chan,
 		party[useridx].flag, party[useridx].sock,
-		safe_str(party[useridx].from));
+		party[useridx].from ? party[useridx].from : "");
     tandout_but(butidx, "chan %s %d %s : %s -> %s.\n",
 		party[useridx].bot, party[useridx].chan,
 		NET_NICKCHANGE,
@@ -770,8 +758,9 @@ void botnet_send_nkch_part(int butidx, int useridx, char *oldnick)
   }
 }
 
-/* this part of add_note is more relevant to the botnet than
- * to the notes file */
+/* This part of add_note is more relevant to the botnet than
+ * to the notes file
+ */
 int add_note(char *to, char *from, char *msg, int idx, int echo)
 {
   int status, i, iaway, sock;
@@ -779,20 +768,20 @@ int add_note(char *to, char *from, char *msg, int idx, int echo)
   struct userrec *u;
 
   if (strlen(msg) > 450)
-    msg[450] = 0;		/* notes have a limit */
+    msg[450] = 0;		/* Notes have a limit */
   /* note length + PRIVMSG header + nickname + date  must be <512  */
   p = strchr(to, '@');
-  if (p != NULL) {		/* cross-bot note */
-    char x[20];
+  if (p != NULL) {		/* Cross-bot note */
+    char x[21];
 
     *p = 0;
     strncpy(x, to, 20);
     x[20] = 0;
     *p = '@';
     p++;
-    if (!strcasecmp(p, botnetnick))	/* to me?? */
-      return add_note(x, from, msg, idx, echo); /* start over, dimwit. */
-    if (strcasecmp(from, botnetnick)) {
+    if (!egg_strcasecmp(p, botnetnick))	/* To me?? */
+      return add_note(x, from, msg, idx, echo); /* Start over, dimwit. */
+    if (egg_strcasecmp(from, botnetnick)) {
       if (strlen(from) > 40)
 	from[40] = 0;
       if (strchr(from, '@')) {
@@ -814,9 +803,9 @@ int add_note(char *to, char *from, char *msg, int idx, int echo)
       botnet_send_priv(i, ssf, x, p, "%s", msg);
     } else
       botnet_send_priv(i, botf, x, p, "%s", msg);
-    return NOTE_OK;		/* forwarded to the right bot */
+    return NOTE_OK;		/* Forwarded to the right bot */
   }
-  /* might be form "sock:nick" */
+  /* Might be form "sock:nick" */
   splitc(ssf, from, ':');
   rmspace(ssf);
   splitc(ss, to, ':');
@@ -825,8 +814,8 @@ int add_note(char *to, char *from, char *msg, int idx, int echo)
     sock = (-1);
   else
     sock = atoi(ss);
-  /* don't process if there's a note binding for it */
-  if (idx != (-2)) {		/* notes from bots don't trigger it */
+  /* Don't process if there's a note binding for it */
+  if (idx != (-2)) {		/* Notes from bots don't trigger it */
     if (check_tcl_note(from, to, msg)) {
       if ((idx >= 0) && (echo))
 	dprintf(idx, "-> %s: %s\n", to, msg);
@@ -850,17 +839,17 @@ int add_note(char *to, char *from, char *msg, int idx, int echo)
   }
   status = NOTE_STORED;
   iaway = 0;
-  /* online right now? */
+  /* Online right now? */
   for (i = 0; i < dcc_total; i++) {
     if ((dcc[i].type->flags & DCT_GETNOTES) &&
 	((sock == (-1)) || (sock == dcc[i].sock)) &&
-	(!strcasecmp(dcc[i].nick, to))) {
+	(!egg_strcasecmp(dcc[i].nick, to))) {
       int aok = 1;
 
       if (dcc[i].type == &DCC_CHAT)
 	if ((dcc[i].u.chat->away != NULL) &&
 	    (idx != (-2))) {
-	  /* only check away if it's not from a bot */
+	  /* Only check away if it's not from a bot */
 	  aok = 0;
 	  if (idx >= 0)
 	    dprintf(idx, "%s %s: %s\n", dcc[i].nick, BOT_USERAWAY,
@@ -881,7 +870,7 @@ int add_note(char *to, char *from, char *msg, int idx, int echo)
 	  else if (*from == '@')
 	    fr = p + 1;
 	}
-	if ((idx == (-2)) || (!strcasecmp(from, botnetnick)))
+	if (idx == -2 || (!egg_strcasecmp(from, botnetnick)))
 	  dprintf(i, "*** [%s] %s%s\n", fr, l ? work : "", msg);
 	else
 	  dprintf(i, "%cNote [%s]: %s%s\n", 7, fr, l ? work : "", msg);
@@ -892,22 +881,20 @@ int add_note(char *to, char *from, char *msg, int idx, int echo)
     }
   }
   if (idx == (-2))
-    return NOTE_OK;		/* error msg from a tandembot: don't store */
-/* call store note here */
+    return NOTE_OK;		/* Error msg from a tandembot: don't store */
+  /* Call store note here */
   Tcl_SetVar(interp, "_from", from, 0);
   Tcl_SetVar(interp, "_to", to, 0);
   Tcl_SetVar(interp, "_data", msg, 0);
   simple_sprintf(ss, "%d", dcc[idx].sock);
   Tcl_SetVar(interp, "_idx", ss, 0);
   if (Tcl_VarEval(interp, "storenote", " $_from $_to $_data $_idx", NULL) == TCL_OK) {
-    if (interp->result && interp->result[0]) {
-      /* strncpy(to, interp->result, NOTENAMELEN);
-      to[NOTENAMELEN] = 0; */ /* notebug fixed ;) -- drummer 29May1999 */
+    if (interp->result && interp->result[0])
       status = NOTE_FWD;
-    }
     if (status == NOTE_AWAY) {
-      /* user is away in all sessions -- just notify the user that a
-       * message arrived and was stored. (only oldest session is notified.) */
+      /* User is away in all sessions -- just notify the user that a
+       * message arrived and was stored. (only oldest session is notified.)
+       */
       dprintf(iaway, "*** %s.\n", BOT_NOTEARRIVED);
     }
     return status;

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 393 - 196
src/botnet.c


+ 126 - 106
src/chan.h

@@ -1,24 +1,24 @@
-/* 
+/*
  * chan.h
  *   stuff common to chan.c and mode.c
  *   users.h needs to be loaded too
- * 
- * $Id: chan.h,v 1.12 2000/01/08 21:23:13 per Exp $
+ *
+ * $Id: chan.h,v 1.29 2002/06/19 21:13:38 wcc Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -28,46 +28,57 @@
 #define _EGG_CHAN_H
 
 typedef struct memstruct {
-  char nick[NICKLEN];		/* "dalnet" allows 30 */
+  char nick[NICKLEN];
   char userhost[UHOSTLEN];
   time_t joined;
   unsigned short flags;
-  time_t split;			/* in case they were just netsplit */
-  time_t last;			/* for measuring idle time */
-  time_t delay;			/* for delayed autoop */
+  time_t split;			/* in case they were just netsplit	*/
+  time_t last;			/* for measuring idle time		*/
+  time_t delay;			/* for delayed autoop			*/
   struct userrec *user;
   struct memstruct *next;
 } memberlist;
 
 #define CHANMETA "#&!+"
+#define NICKVALID "[{}]^`|\\_-"
 
-#define CHANOP      0x0001	/* channel +o */
-#define CHANVOICE   0x0002	/* channel +v */
-#define FAKEOP      0x0004	/* op'd by server */
-#define SENTOP      0x0008	/* a mode +o was already sent out for
-				   * this user */
-#define SENTDEOP    0x0010	/* a mode -o was already sent out for
-				   * this user */
-#define SENTKICK    0x0020	/* a kick was already sent out for this user */
-#define SENTVOICE   0x0040	/* a mode +v was already sent out for
-				   * this user */
-#define SENTDEVOICE 0x0080	/* a devoice has been sent */
-#define WASOP       0x0100	/* was an op before a split */
-#define STOPWHO     0x0200
+#define CHANOP       0x00001 /* channel +o                                   */
+#define CHANVOICE    0x00002 /* channel +v                                   */
+#define FAKEOP       0x00004 /* op'd by server                               */
+#define SENTOP       0x00008 /* a mode +o was already sent out for this user */
+#define SENTDEOP     0x00010 /* a mode -o was already sent out for this user */
+#define SENTKICK     0x00020 /* a kick was already sent out for this user    */
+#define SENTVOICE    0x00040 /* a mode +v was already sent out for this user */
+#define SENTDEVOICE  0x00080 /* a devoice has been sent                      */
+#define WASOP        0x00100 /* was an op before a split                     */
+#define STOPWHO      0x00200
+#define FULL_DELAY   0x00400
+#define STOPCHECK    0x00800
+#define CHANHALFOP   0x01000 /* channel +h                                   */
+#define FAKEHALFOP   0x02000 /* halfop'd by server                           */
+#define SENTHALFOP   0x04000 /* a mode +h was already sent out for this user */
+#define SENTDEHALFOP 0x08000 /* a mode -h was already sent out for this user */
+#define WASHALFOP    0x10000 /* was a halfop before a split                  */
 
 #define chan_hasvoice(x) (x->flags & CHANVOICE)
 #define chan_hasop(x) (x->flags & CHANOP)
+#define chan_hashalfop(x) (x->flags & CHANHALFOP)
 #define chan_fakeop(x) (x->flags & FAKEOP)
+#define chan_fakehalfop(x) (x->flags & FAKEHALFOP)
 #define chan_sentop(x) (x->flags & SENTOP)
 #define chan_sentdeop(x) (x->flags & SENTDEOP)
+#define chan_senthalfop(x) (x->flags & SENTHALFOP)
+#define chan_sentdehalfop(x) (x->flags & SENTDEHALFOP)
 #define chan_sentkick(x) (x->flags & SENTKICK)
 #define chan_sentvoice(x) (x->flags & SENTVOICE)
 #define chan_sentdevoice(x) (x->flags & SENTDEVOICE)
 #define chan_issplit(x) (x->split > 0)
 #define chan_wasop(x) (x->flags & WASOP)
+#define chan_washalfop(x) (x->flags & WASHALFOP)
+#define chan_stopcheck(x) (x->flags & STOPCHECK)
 
-/*        Why duplicate this struct for exempts and invites only under another
- *      name? <cybah>
+/* Why duplicate this struct for exempts and invites only under another
+ * name? <cybah>
  */
 typedef struct maskstruct {
   char *mask;
@@ -76,7 +87,7 @@ typedef struct maskstruct {
   struct maskstruct *next;
 } masklist;
 
-/* used for temporary bans, exempts and invites */
+/* Used for temporary bans, exempts and invites */
 typedef struct maskrec {
   struct maskrec *next;
   char *mask,
@@ -92,7 +103,7 @@ extern maskrec *global_bans, *global_exempts, *global_invites;
 #define MASKREC_STICKY 1
 #define MASKREC_PERM   2
 
-/* for every channel i join */
+/* For every channel i join */
 struct chan_t {
   memberlist *member;
   masklist *ban;
@@ -105,22 +116,30 @@ struct chan_t {
   int members;
 };
 
-#define CHANINV    0x0001	/* +i */
-#define CHANPRIV   0x0002	/* +p */
-#define CHANSEC    0x0004	/* +s */
-#define CHANMODER  0x0008	/* +m */
-#define CHANTOPIC  0x0010	/* +t */
-#define CHANNOMSG  0x0020	/* +n */
-#define CHANLIMIT  0x0040	/* -l -- used only for protecting modes */
-#define CHANKEY    0x0080	/* +k */
-#define CHANANON   0x0100	/* +a -- ircd 2.9 */
-#define CHANQUIET  0x0200	/* +q -- ircd 2.9 */
+#define CHANINV    0x0001	/* +i					*/
+#define CHANPRIV   0x0002	/* +p					*/
+#define CHANSEC    0x0004	/* +s					*/
+#define CHANMODER  0x0008	/* +m					*/
+#define CHANTOPIC  0x0010	/* +t					*/
+#define CHANNOMSG  0x0020	/* +n					*/
+#define CHANLIMIT  0x0040	/* -l -- used only for protecting modes	*/
+#define CHANKEY    0x0080	/* +k					*/
+#define CHANANON   0x0100	/* +a -- ircd 2.9			*/
+#define CHANQUIET  0x0200	/* +q -- ircd 2.9			*/
+#define CHANNOCLR  0x0400	/* +c -- bahamut			*/
+#define CHANREGON  0x0800	/* +R -- bahamut			*/
+#define CHANMODR   0x1000	/* +M -- bahamut			*/
+#define CHANNOCTCP 0x2000      /* +C -- QuakeNet's ircu 2.10           */
+#define CHANLONLY  0x4000      /* +r -- ircu 2.10.11                   */
 
-/* for every channel i'm supposed to be active on */
+/* For every channel i'm supposed to be active on */
 struct chanset_t {
   struct chanset_t *next;
-  struct chan_t channel;	/* current information */
-  char name[81];
+  struct chan_t channel;	/* current information			*/
+  char dname[81];               /* what the users know the channel as,
+				   like !eggdev				*/
+  char name[81];                /* what the servers know the channel
+				   as, like !ABCDEeggdev		*/
   char need_op[121];
   char need_key[121];
   char need_limit[121];
@@ -136,71 +155,76 @@ struct chanset_t {
   int flood_kick_time;
   int flood_ctcp_thr;
   int flood_ctcp_time;
+  int flood_nick_thr;
+  int flood_nick_time;
+  int aop_min;
+  int aop_max;
   int status;
   int ircnet_status;
   int idle_kick;
-  /* temporary channel bans, exempts and invites */
-  maskrec *bans,
-          *exempts,
-          *invites;
+  int stopnethack_mode;
+  int revenge_mode;
+  maskrec *bans,		/* temporary channel bans		*/
+          *exempts,		/* temporary channel exempts		*/
+          *invites;		/* temporary channel invites		*/
   /* desired channel modes: */
-  int mode_pls_prot;		/* modes to enforce */
-  int mode_mns_prot;		/* modes to reject */
-  int limit_prot;		/* desired limit */
-  char key_prot[121];		/* desired password */
+  int mode_pls_prot;		/* modes to enforce			*/
+  int mode_mns_prot;		/* modes to reject			*/
+  int limit_prot;		/* desired limit			*/
+  char key_prot[121];		/* desired password			*/
   /* queued mode changes: */
-  char pls[21];			/* positive mode changes */
-  char mns[21];			/* negative mode changes */
-  char key[81];			/* new key to set */
-  char rmkey[81];		/* old key to remove */
-  int limit;			/* new limit to set */
-  int bytes;			/* total bytes so far */
-  int compat;           /* to prevent mixing old/new modes */
+  char pls[21];			/* positive mode changes		*/
+  char mns[21];			/* negative mode changes		*/
+  char *key;			/* new key to set			*/
+  char *rmkey;			/* old key to remove			*/
+  int limit;			/* new limit to set			*/
+  int bytes;			/* total bytes so far			*/
+  int compat;			/* to prevent mixing old/new modes	*/
   struct {
     char *op;
-    char type;
-  } cmode[6];			/* parameter-type mode changes - */
+    int type;
+  } cmode[6];			/* parameter-type mode changes -	*/
   /* detect floods */
   char floodwho[FLOOD_CHAN_MAX][81];
   time_t floodtime[FLOOD_CHAN_MAX];
   int floodnum[FLOOD_CHAN_MAX];
-  char deopd[NICKLEN];		/* last person deop'd (must change) */
+  char deopd[NICKLEN];		/* last person deop'd (must change	*/
 };
 
 /* behavior modes for the channel */
-#define CHAN_CLEARBANS      0x0001	/* clear bans on join */
-#define CHAN_ENFORCEBANS    0x0002	/* kick people who match channel bans */
-#define CHAN_DYNAMICBANS    0x0004	/* only activate bans when needed */
-#define CHAN_NOUSERBANS     0x0008	/* don't let non-bots place bans */
-#define CHAN_OPONJOIN       0x0010	/* op +o people as soon as they join */
-#define CHAN_BITCH          0x0020	/* be a tightwad with ops */
-#define CHAN_GREET          0x0040	/* greet people with their info line */
-#define CHAN_PROTECTOPS     0x0080	/* re-op any +o people who get deop'd */
-#define CHAN_LOGSTATUS      0x0100	/* log channel status every 5 mins */
-#define CHAN_STOPNETHACK    0x0200	/* deop netsplit hackers */
-#define CHAN_REVENGE        0x0400	/* get revenge on bad people */
-#define CHAN_SECRET         0x0800	/* don't advertise channel on botnet */
-#define CHAN_AUTOVOICE      0x1000	/* dish out voice stuff automatically */
-#define CHAN_CYCLE          0x2000	/* cycle the channel if possible */
-#define CHAN_DONTKICKOPS    0x4000	/* never kick +o flag people - arthur2 */
-#define CHAN_WASOPTEST      0x8000	/* wasop test for all +o user
-					 * when +stopnethack */
-#define CHAN_INACTIVE       0x10000	/* no irc support for this channel - drummer */
-#define CHAN_PROTECTFRIENDS 0x20000     /* re-op any +f people who get deop'd */
-#define CHAN_SHARED         0x40000	/* channel is being shared */
-#define CHAN_SEEN           0x80000
-#define CHAN_REVENGEBOT     0x100000	/* revenge on actions against the bot */
-/*			    0x200000 */
-/*			    0x400000 */
-/*			    0x800000 */
-#define CHAN_ACTIVE         0x1000000	/* like i'm actually on the channel
-					 * and stuff */
-#define CHAN_PEND           0x2000000	/* just joined; waiting for end of
-					 * WHO list */
-#define CHAN_FLAGGED        0x4000000	/* flagged during rehash for delete */
-#define CHAN_STATIC         0x8000000	/* channels that are NOT dynamic */
+#define CHAN_ENFORCEBANS    0x0001	   /* kick people who match channel bans */
+#define CHAN_DYNAMICBANS    0x0002	   /* only activate bans when needed     */
+#define CHAN_NOUSERBANS     0x0004	   /* don't let non-bots place bans      */
+#define CHAN_OPONJOIN       0x0008	   /* op +o people as soon as they join  */
+#define CHAN_BITCH          0x0010	   /* be a tightwad with ops             */
+#define CHAN_GREET          0x0020	   /* greet people with their info line  */
+#define CHAN_PROTECTOPS     0x0040	   /* re-op any +o people who get deop'd */
+#define CHAN_LOGSTATUS      0x0080	   /* log channel status every 5 mins    */
+#define CHAN_REVENGE        0x0100	   /* get revenge on bad people          */
+#define CHAN_SECRET         0x0200	   /* don't advertise channel on botnet  */
+#define CHAN_AUTOVOICE      0x0400	   /* dish out voice stuff automatically */
+#define CHAN_CYCLE          0x0800	   /* cycle the channel if possible      */
+#define CHAN_DONTKICKOPS    0x1000	   /* never kick +o flag people -arthur2 */
+#define CHAN_INACTIVE       0x2000	   /* no irc support for this channel
+                                         - drummer                           */
+#define CHAN_PROTECTFRIENDS 0x4000	   /* re-op any +f people who get deop'd */
+#define CHAN_SHARED         0x8000	   /* channel is being shared            */
+#define CHAN_SEEN           0x10000
+#define CHAN_REVENGEBOT     0x20000	   /* revenge on actions against the bot */
+#define CHAN_NODESYNCH      0x40000
+#define CHAN_AUTOHALFOP     0x80000    /* op +h people on join               */ 
+#define CHAN_PROTECTHALFOPS 0x100000   /* op +h people on join               */ 
+#define CHAN_ACTIVE         0x1000000  /* like i'm actually on the channel
+                                          and stuff                          */
+#define CHAN_PEND           0x2000000  /* just joined; waiting for end of
+                                          WHO list                           */
+#define CHAN_FLAGGED        0x4000000  /* flagged during rehash for delete   */
+#define CHAN_STATIC         0x8000000  /* channels that are NOT dynamic      */
 #define CHAN_ASKEDBANS      0x10000000
-#define CHAN_ASKEDMODES     0x20000000  /* find out key-info on IRCu */
+#define CHAN_ASKEDMODES     0x20000000 /* find out key-info on IRCu          */
+#define CHAN_JUPED          0x40000000 /* Is channel juped                   */
+#define CHAN_STOP_CYCLE     0x80000000 /* Some efnetservers have defined
+                                          NO_CHANOPS_WHEN_SPLIT              */
 
 #define CHAN_ASKED_EXEMPTS  0x0001
 #define CHAN_ASKED_INVITED  0x0002
@@ -212,29 +236,31 @@ struct chanset_t {
 
 /* prototypes */
 memberlist *ismember(struct chanset_t *, char *);
-struct chanset_t *findchan();
+struct chanset_t *findchan(const char *name);
+struct chanset_t *findchan_by_dname(const char *name);
 
 /* is this channel +s/+p? */
 #define channel_hidden(chan) (chan->channel.mode & (CHANPRIV | CHANSEC))
 /* is this channel +t? */
 #define channel_optopic(chan) (chan->channel.mode & CHANTOPIC)
+
 #define channel_active(chan)  (chan->status & CHAN_ACTIVE)
 #define channel_pending(chan)  (chan->status & CHAN_PEND)
 #define channel_bitch(chan) (chan->status & CHAN_BITCH)
+#define channel_nodesynch(chan) (chan->status & CHAN_NODESYNCH)
 #define channel_autoop(chan) (chan->status & CHAN_OPONJOIN)
-#define channel_wasoptest(chan) (chan->status & CHAN_WASOPTEST)
 #define channel_autovoice(chan) (chan->status & CHAN_AUTOVOICE)
+#define channel_autohalfop(chan) (chan->status & CHAN_AUTOHALFOP)
 #define channel_greet(chan) (chan->status & CHAN_GREET)
 #define channel_logstatus(chan) (chan->status & CHAN_LOGSTATUS)
-#define channel_clearbans(chan) (chan->status & CHAN_CLEARBANS)
 #define channel_enforcebans(chan) (chan->status & CHAN_ENFORCEBANS)
 #define channel_revenge(chan) (chan->status & CHAN_REVENGE)
 #define channel_dynamicbans(chan) (chan->status & CHAN_DYNAMICBANS)
 #define channel_nouserbans(chan) (chan->status & CHAN_NOUSERBANS)
 #define channel_protectops(chan) (chan->status & CHAN_PROTECTOPS)
+#define channel_protecthalfops(chan) (chan->status & CHAN_PROTECTHALFOPS)
 #define channel_protectfriends(chan) (chan->status & CHAN_PROTECTFRIENDS)
 #define channel_dontkickops(chan) (chan->status & CHAN_DONTKICKOPS)
-#define channel_stopnethack(chan) (chan->status & CHAN_STOPNETHACK)
 #define channel_secret(chan) (chan->status & CHAN_SECRET)
 #define channel_shared(chan) (chan->status & CHAN_SHARED)
 #define channel_static(chan) (chan->status & CHAN_STATIC)
@@ -246,14 +272,8 @@ struct chanset_t *findchan();
 #define channel_nouserexempts(chan) (chan->ircnet_status & CHAN_NOUSEREXEMPTS)
 #define channel_dynamicinvites(chan) (chan->ircnet_status & CHAN_DYNAMICINVITES)
 #define channel_nouserinvites(chan) (chan->ircnet_status & CHAN_NOUSERINVITES)
-
-struct server_list {
-  struct server_list *next;
-  char *name;
-  int port;
-  char *pass;
-  char *realname;
-};
+#define channel_juped(chan) (chan->status & CHAN_JUPED)
+#define channel_stop_cycle(chan) (chan->status & CHAN_STOP_CYCLE)
 
 struct msgq_head {
   struct msgq *head;
@@ -262,7 +282,7 @@ struct msgq_head {
   int warned;
 };
 
-/* used to queue a lot of things */
+/* Used to queue a lot of things */
 struct msgq {
   struct msgq *next;
   int len;

+ 238 - 211
src/chanprog.c

@@ -1,4 +1,4 @@
-/* 
+/*
  * chanprog.c -- handles:
  *   rmspace()
  *   maintaining the server list
@@ -6,26 +6,23 @@
  *   timers, utimers
  *   telling the current programmed settings
  *   initializing a lot of stuff and loading the tcl scripts
- * 
- * config file format changed 27jan1994 (Tcl outdates that)
- * dprintf'ized, 1nov1995
- * 
- * $Id: chanprog.c,v 1.19 2000/01/08 21:23:13 per Exp $
+ *
+ * $Id: chanprog.c,v 1.32 2002/07/18 20:28:32 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -43,37 +40,40 @@
 #endif
 #include "modules.h"
 
-extern struct userrec *userlist;
-extern log_t *logs;
-extern Tcl_Interp *interp;
-extern char ver[], botnetnick[], firewall[];
-extern char motdfile[], userfile[], helpdir[], tempdir[];
-extern char moddir[], notify_new[], owner[], configfile[];
-extern time_t now, online_since;
-extern int backgrd, term_z, con_chan, cache_hit, cache_miss, firewallport;
-extern int default_flags, max_logs, conmask, protect_readonly, make_userfile;
-extern int noshare, ignore_time;
-
-tcl_timer_t *timer = NULL, *utimer = NULL;	/* timers (minutely) and
-						 * utimers (secondly) */
-unsigned long timer_id = 1;	/* next timer of any sort will have this
-				 * number */
-struct chanset_t *chanset = NULL;	/* channel list */
-char admin[121] = "";		/* admin info */
-char origbotname[NICKLEN + 1];
-char botname[NICKLEN + 1];	/* primary botname */
-
-/* remove space characters from beginning and end of string */
-/* (more efficent by Fred1) */
+extern struct userrec	*userlist;
+extern log_t		*logs;
+extern Tcl_Interp	*interp;
+extern char		 ver[], botnetnick[], firewall[],
+			 motdfile[], userfile[], helpdir[], tempdir[],
+			 moddir[], notify_new[], owner[], configfile[];
+extern time_t		 now, online_since;
+extern int		 backgrd, term_z, con_chan, cache_hit, cache_miss,
+			 firewallport, default_flags, max_logs, conmask,
+			 protect_readonly, make_userfile, noshare,
+			 ignore_time;
+
+tcl_timer_t	 *timer = NULL;		/* Minutely timer		*/
+tcl_timer_t	 *utimer = NULL;	/* Secondly timer		*/
+unsigned long	  timer_id = 1;		/* Next timer of any sort will
+					   have this number		*/
+struct chanset_t *chanset = NULL;	/* Channel list			*/
+char		  admin[121] = "";	/* Admin info			*/
+char		  origbotname[NICKLEN + 1];
+char		  botname[NICKLEN + 1];	/* Primary botname		*/
+
+
+/* Remove space characters from beginning and end of string
+ * (more efficent by Fred1)
+ */
 void rmspace(char *s)
 {
-#define whitespace(c) ( ((c)==32) || ((c)==9) || ((c)==13) || ((c)==10) )
+#define whitespace(c) (((c) == 32) || ((c) == 9) || ((c) == 13) || ((c) == 10))
   char *p;
 
   if (*s == '\0')
 	return;
 
-  /* wipe end of string */
+  /* Wipe end of string */
   for (p = s + strlen(s) - 1; ((whitespace(*p)) && (p >= s)); p--);
   if (p != s + strlen(s) - 1)
     *(p + 1) = 0;
@@ -82,138 +82,145 @@ void rmspace(char *s)
     strcpy(s, p);
 }
 
-/* returns memberfields if the nick is in the member list */
+/* Returns memberfields if the nick is in the member list.
+ */
 memberlist *ismember(struct chanset_t *chan, char *nick)
 {
-  memberlist *x;
-
-  x = chan->channel.member;
-  while (x && x->nick[0] && rfc_casecmp(x->nick, nick))
-    x = x->next;
-  if (!x->nick[0])
-    return NULL;
-  return x;
+  register memberlist	*x;
+
+  for (x = chan->channel.member; x && x->nick[0]; x = x->next)
+    if (!rfc_casecmp(x->nick, nick))
+      return x;
+  return NULL;
 }
 
-/* find a chanset by channel name */
-struct chanset_t *findchan(char *name)
+/* Find a chanset by channel name as the server knows it (ie !ABCDEchannel)
+ */
+struct chanset_t *findchan(const char *name)
 {
-  struct chanset_t *chan = chanset;
+  register struct chanset_t	*chan;
 
-  while (chan != NULL) {
+  for (chan = chanset; chan; chan = chan->next)
     if (!rfc_casecmp(chan->name, name))
       return chan;
-    chan = chan->next;
-  }
   return NULL;
 }
 
-/* stupid "caching" functions */
-/* shortcut for get_user_by_host -- might have user record in one
- * of the channel caches */
-struct userrec *check_chanlist(char *host)
+/* Find a chanset by display name (ie !channel)
+ */
+struct chanset_t *findchan_by_dname(const char *name)
+{
+  register struct chanset_t	*chan;
+
+  for (chan = chanset; chan; chan = chan->next)
+    if (!rfc_casecmp(chan->dname, name))
+      return chan;
+  return NULL;
+}
+
+/*
+ *    "caching" functions
+ */
+
+/* Shortcut for get_user_by_host -- might have user record in one
+ * of the channel caches.
+ */
+struct userrec *check_chanlist(const char *host)
 {
-  char *nick, *uhost, buf[UHOSTLEN];
-  memberlist *m;
-  struct chanset_t *chan;
+  char				*nick, *uhost, buf[UHOSTLEN];
+  register memberlist		*m;
+  register struct chanset_t	*chan;
 
-  strncpy(buf, host, UHOSTMAX);
-  buf[UHOSTMAX] = 0;	/* why is this case sanely done, when there
-			 * are so many others? */
+  strncpyz(buf, host, sizeof buf);
   uhost = buf;
   nick = splitnick(&uhost);
-  for (chan = chanset; chan; chan = chan->next) {
-    m = chan->channel.member;
-    while (m && m->nick[0]) {
-      if (!rfc_casecmp(nick, m->nick) &&
-	  !strcasecmp(uhost, m->userhost))
+  for (chan = chanset; chan; chan = chan->next)
+    for (m = chan->channel.member; m && m->nick[0]; m = m->next)
+      if (!rfc_casecmp(nick, m->nick) && !egg_strcasecmp(uhost, m->userhost))
 	return m->user;
-      m = m->next;
-    }
-  }
   return NULL;
 }
 
-/* shortcut for get_user_by_handle -- might have user record in channels */
-struct userrec *check_chanlist_hand(char *hand)
+/* Shortcut for get_user_by_handle -- might have user record in channels
+ */
+struct userrec *check_chanlist_hand(const char *hand)
 {
-  struct chanset_t *chan = chanset;
-  memberlist *m;
-
-  while (chan) {
-    m = chan->channel.member;
-    while (m && m->nick[0]) {
-      if (m->user)
-	if (!strcasecmp(m->user->handle, hand))
-	  return m->user;
-      m = m->next;
-    }
-    chan = chan->next;
-  }
+  register struct chanset_t	*chan;
+  register memberlist		*m;
+
+  for (chan = chanset; chan; chan = chan->next)
+    for (m = chan->channel.member; m && m->nick[0]; m = m->next)
+      if (m->user && !egg_strcasecmp(m->user->handle, hand))
+	return m->user;
   return NULL;
 }
 
-/* clear the user pointers in the chanlists */
-/* (necessary when a hostmask is added/removed or a user is added) */
-void clear_chanlist()
+/* Clear the user pointers in the chanlists.
+ *
+ * Necessary when a hostmask is added/removed, a user is added or a new
+ * userfile is loaded.
+ */
+void clear_chanlist(void)
 {
-  memberlist *m;
-  struct chanset_t *chan = chanset;
+  register memberlist		*m;
+  register struct chanset_t	*chan;
 
-  while (chan) {
-    m = chan->channel.member;
-    while (m && m->nick[0]) {
+  for (chan = chanset; chan; chan = chan->next)
+    for (m = chan->channel.member; m && m->nick[0]; m = m->next)
       m->user = NULL;
-      m = m->next;
-    }
-    chan = chan->next;
-  }
 }
 
-/* if this user@host is in a channel, set it (it was null) */
-void set_chanlist(char *host, struct userrec *rec)
+/* Clear the user pointer of a specific nick in the chanlists.
+ *
+ * Necessary when a hostmask is added/removed, a nick changes, etc.
+ * Does not completely invalidate the channel cache like clear_chanlist().
+ */
+void clear_chanlist_member(const char *nick)
+{
+  register memberlist		*m;
+  register struct chanset_t	*chan;
+
+  for (chan = chanset; chan; chan = chan->next)
+    for (m = chan->channel.member; m && m->nick[0]; m = m->next)
+      if (!rfc_casecmp(m->nick, nick)) {
+	m->user = NULL;
+	break;
+      }
+}
+
+/* If this user@host is in a channel, set it (it was null)
+ */
+void set_chanlist(const char *host, struct userrec *rec)
 {
-  char *nick, *uhost, buf[UHOSTLEN];
-  memberlist *m;
-  struct chanset_t *chan = chanset;
+  char				*nick, *uhost, buf[UHOSTLEN];
+  register memberlist		*m;
+  register struct chanset_t	*chan;
 
-  Context;
-  strncpy(buf, host, UHOSTMAX);
-  buf[UHOSTMAX] = 0;
+  strncpyz(buf, host, sizeof buf);
   uhost = buf;
   nick = splitnick(&uhost);
-  while (chan) {
-    m = chan->channel.member;
-    while (m && m->nick[0]) {
-      if (!rfc_casecmp(nick, m->nick) &&
-	  !strcasecmp(uhost, m->userhost))
+  for (chan = chanset; chan; chan = chan->next)
+    for (m = chan->channel.member; m && m->nick[0]; m = m->next)
+      if (!rfc_casecmp(nick, m->nick) && !egg_strcasecmp(uhost, m->userhost))
 	m->user = rec;
-      m = m->next;
-    }
-    chan = chan->next;
-  }
 }
 
-/* memory we should be using */
+/* Calculate the memory we should be using
+ */
 int expmem_chanprog()
 {
-  int tot;
-  tcl_timer_t *t;
-
-  Context;
-  tot = 0;
-  for (t = timer; t; t = t->next) {
-    tot += sizeof(tcl_timer_t);
-    tot += strlen(t->cmd) + 1;
-  }
-  for (t = utimer; t; t = t->next) {
-    tot += sizeof(tcl_timer_t);
-    tot += strlen(t->cmd) + 1;
-  }
+  register int		 tot = 0;
+  register tcl_timer_t	*t;
+
+  for (t = timer; t; t = t->next)
+    tot += sizeof(tcl_timer_t) + strlen(t->cmd) + 1;
+  for (t = utimer; t; t = t->next)
+    tot += sizeof(tcl_timer_t) + strlen(t->cmd) + 1;
   return tot;
 }
 
-/* dump uptime info out to dcc (guppy 9Jan99) */
+/* Dump uptime info out to dcc (guppy 9Jan99)
+ */
 void tell_verbose_uptime(int idx)
 {
   char s[256], s1[121];
@@ -247,22 +254,20 @@ void tell_verbose_uptime(int idx)
   dprintf(idx, "%s %s  (%s)\n", MISC_ONLINEFOR, s, s1);
 }
 
-/* dump status info out to dcc */
+/* Dump status info out to dcc
+ */
 void tell_verbose_status(int idx)
 {
   char s[256], s1[121], s2[81];
   char *vers_t, *uni_t;
   int i;
   time_t now2, hr, min;
-
 #if HAVE_GETRUSAGE
   struct rusage ru;
-
 #else
-#if HAVE_CLOCK
+# if HAVE_CLOCK
   clock_t cl;
-
-#endif
+# endif
 #endif
 #ifdef HAVE_UNAME
   struct utsname un;
@@ -282,9 +287,7 @@ void tell_verbose_status(int idx)
   dprintf(idx, "I am %s, running %s:  %d user%s (mem: %uk)\n",
 	  botnetnick, ver, i, i == 1 ? "" : "s",
           (int) (expected_memory() / 1024));
-  dprintf(idx, "Running on %s %s\n", uni_t, vers_t);
-  if (admin[0])
-    dprintf(idx, "Admin: %s\n", admin);
+
   now2 = now - online_since;
   s[0] = 0;
   if (now2 > 86400) {
@@ -314,32 +317,52 @@ void tell_verbose_status(int idx)
   getrusage(RUSAGE_SELF, &ru);
   hr = (int) ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) / 60);
   min = (int) ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) - (hr * 60));
-  sprintf(s2, "CPU %02d:%02d", (int) hr, (int) min);	/* actally min/sec */
+  sprintf(s2, "CPU %02d:%02d", (int) hr, (int) min);	/* Actally min/sec */
 #else
-#if HAVE_CLOCK
+# if HAVE_CLOCK
   cl = (clock() / CLOCKS_PER_SEC);
   hr = (int) (cl / 60);
   min = (int) (cl - (hr * 60));
-  sprintf(s2, "CPU %02d:%02d", (int) hr, (int) min);	/* actually min/sec */
-#else
+  sprintf(s2, "CPU %02d:%02d", (int) hr, (int) min);	/* Actually min/sec */
+# else
   sprintf(s2, "CPU ???");
-#endif
+# endif
 #endif
   dprintf(idx, "%s %s  (%s)  %s  %s %4.1f%%\n", MISC_ONLINEFOR,
 	  s, s1, s2, MISC_CACHEHIT,
-       100.0 * ((float) cache_hit) / ((float) (cache_hit + cache_miss)));
-  strcpy(s, "info library");
-  if ((interp) && (Tcl_Eval(interp, s) == TCL_OK))
-    dprintf(idx, "%s %s\n", MISC_TCLLIBVER, interp->result);
+	  100.0 * ((float) cache_hit) / ((float) (cache_hit + cache_miss)));
+
+  if (admin[0])
+    dprintf(idx, "Admin: %s\n", admin);
+
+  dprintf(idx, "Config file: %s\n", configfile);
+  dprintf(idx, "OS: %s %s\n", uni_t, vers_t);
+
+  /* info library */
+  dprintf(idx, "%s %s\n", MISC_TCLLIBRARY,
+	  ((interp) && (Tcl_Eval(interp, "info library") == TCL_OK)) ?
+	  interp->result : "*unknown*");
+
+  /* info tclversion/patchlevel */
+  dprintf(idx, "%s %s (%s %s)\n", MISC_TCLVERSION,
+	  ((interp) && (Tcl_Eval(interp, "info patchlevel") == TCL_OK)) ?
+	  interp->result : (Tcl_Eval(interp, "info tclversion") == TCL_OK) ?
+	  interp->result : "*unknown*", MISC_TCLHVERSION,
+	  TCL_PATCH_LEVEL ? TCL_PATCH_LEVEL : "*unknown*");
+
+#if HAVE_TCL_THREADS
+  dprintf(idx, "Tcl is threaded\n");
+#endif  
+	  
 }
 
-/* show all internal state variables */
+/* Show all internal state variables
+ */
 void tell_settings(int idx)
 {
   char s[1024];
   int i;
-  struct flag_record fr =
-  {FR_GLOBAL, 0, 0, 0, 0, 0};
+  struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
 
   dprintf(idx, "Botnet Nickname: %s\n", botnetnick);
   if (firewall[0])
@@ -372,13 +395,12 @@ void reaffirm_owners()
   char *p, *q, s[121];
   struct userrec *u;
 
-  /* make sure default owners are +n */
+  /* Make sure default owners are +n */
   if (owner[0]) {
     q = owner;
     p = strchr(q, ',');
     while (p) {
-      strncpy(s, q, p - q);
-      s[p - q] = 0;
+      strncpyz(s, q, p - q);
       rmspace(s);
       u = get_user_by_handle(userlist, s);
       if (u)
@@ -404,10 +426,9 @@ void chanprog()
   for (i = 0; i < max_logs; i++)
     logs[i].flags |= LF_EXPIRING;
   conmask = 0;
-  /* turn off read-only variables (make them write-able) for rehash */
+  /* Turn off read-only variables (make them write-able) for rehash */
   protect_readonly = 0;
-  /* now read it */
-  Context;
+  /* Now read it */
   if (!readtclprog(configfile))
     fatal(MISC_NOCONFIGFILE, 0);
   for (i = 0; i < max_logs; i++) {
@@ -430,19 +451,22 @@ void chanprog()
   }
   /* We should be safe now */
   call_hook(HOOK_REHASH);
-  Context;
   protect_readonly = 1;
+  if (!botnetnick[0]) {
+    strncpyz(botnetnick, origbotname, HANDLEN + 1);
+  }
+  if (!botnetnick[0])
+    fatal("I don't have a botnet nick!!\n", 0);
   if (!userfile[0])
     fatal(MISC_NOUSERFILE2, 0);
-  if ((int) getuid() == 0) {
-    /* perhaps you should make it run something innocent here ;)
-     * like rm -rf /etc :) */
-    printf("\n\n%s\n", MISC_ROOTWARN);
-  }
   if (!readuserfile(userfile, &userlist)) {
-    if (!make_userfile)
-      fatal(MISC_NOUSERFILE, 0);
-    printf("\n\n%s\n", MISC_USERFCREATE);
+    if (!make_userfile) {
+      char tmp[178];
+
+      egg_snprintf(tmp, sizeof tmp, MISC_NOUSERFILE, configfile);
+      fatal(tmp, 0);
+    }
+    printf("\n\n%s\n", MISC_NOUSERFILE2);
     if (module_find("server", 0, 0))
       printf(MISC_USERFCREATE1, origbotname);
     printf("%s\n\n", MISC_USERFCREATE2);
@@ -450,27 +474,23 @@ void chanprog()
      make_userfile = 0;
      printf("%s\n", MISC_USERFEXISTS);
   }
-  Context;
   if (helpdir[0])
     if (helpdir[strlen(helpdir) - 1] != '/')
       strcat(helpdir, "/");
   if (tempdir[0])
     if (tempdir[strlen(tempdir) - 1] != '/')
       strcat(tempdir, "/");
-  if (!botnetnick[0]) {
-    strncpy(botnetnick, origbotname, HANDLEN);
-    botnetnick[HANDLEN] = 0;
-  }
-  if (!botnetnick[0])
-    fatal("I don't have a botnet nick!!\n", 0);
-  Context;
-  /* test tempdir: it's vital */
+  /* Test tempdir: it's vital */
   {
     FILE *f;
     char s[161], rands[8];
 
-    /* possible file race condition solved by using a random string 
-     * and the process id in the filename */
+    /* Possible file race condition solved by using a random string
+     * and the process id in the filename.
+     * FIXME: This race is only partitially fixed. We could still be
+     *        overwriting an existing file / following a malicious
+     *        link.
+     */
     make_rand_str(rands, 7); /* create random string */
     sprintf(s, "%s.test-%u-%s", tempdir, getpid(), rands);
     f = fopen(s, "w");
@@ -479,11 +499,11 @@ void chanprog()
     fclose(f);
     unlink(s);
   }
-  Context;
   reaffirm_owners();
 }
 
-/* reload the user file from disk */
+/* Reload the user file from disk
+ */
 void reload()
 {
   FILE *f;
@@ -500,7 +520,6 @@ void reload()
   userlist = NULL;
   if (!readuserfile(userfile, &userlist))
     fatal(MISC_MISSINGUSERF, 0);
-  Context;
   reaffirm_owners();
   call_hook(HOOK_READ_USERFILE);
 }
@@ -515,10 +534,13 @@ void rehash()
   chanprog();
 }
 
-/* brief venture into timers */
+/*
+ *    Brief venture into timers
+ */
 
-/* add a timer */
-unsigned long add_timer(tcl_timer_t ** stack, int elapse, char *cmd,
+/* Add a timer
+ */
+unsigned long add_timer(tcl_timer_t **stack, int elapse, char *cmd,
 			unsigned long prev_id)
 {
   tcl_timer_t *old = (*stack);
@@ -528,8 +550,9 @@ unsigned long add_timer(tcl_timer_t ** stack, int elapse, char *cmd,
   (*stack)->mins = elapse;
   (*stack)->cmd = (char *) nmalloc(strlen(cmd) + 1);
   strcpy((*stack)->cmd, cmd);
-  /* if it's just being added back and already had an id,
-   * don't create a new one */
+  /* If it's just being added back and already had an id,
+   * don't create a new one.
+  */
   if (prev_id > 0)
     (*stack)->id = prev_id;
   else
@@ -537,8 +560,9 @@ unsigned long add_timer(tcl_timer_t ** stack, int elapse, char *cmd,
   return (*stack)->id;
 }
 
-/* remove a timer, by id */
-int remove_timer(tcl_timer_t ** stack, unsigned long id)
+/* Remove a timer, by id
+ */
+int remove_timer(tcl_timer_t **stack, unsigned long id)
 {
   tcl_timer_t *old;
   int ok = 0;
@@ -556,39 +580,38 @@ int remove_timer(tcl_timer_t ** stack, unsigned long id)
   return ok;
 }
 
-/* check timers, execute the ones that have expired */
-void do_check_timers(tcl_timer_t ** stack)
+/* Check timers, execute the ones that have expired.
+ */
+void do_check_timers(tcl_timer_t **stack)
 {
   tcl_timer_t *mark = *stack, *old = NULL;
-  char x[30];
+  char x[16];
 
-  /* new timers could be added by a Tcl script inside a current timer */
-  /* so i'll just clear out the timer list completely, and add any
-   * unexpired timers back on */
-  Context;
+  /* New timers could be added by a Tcl script inside a current timer
+   * so i'll just clear out the timer list completely, and add any
+   * unexpired timers back on.
+   */
   *stack = NULL;
   while (mark) {
-    Context;
     if (mark->mins > 0)
       mark->mins--;
     old = mark;
     mark = mark->next;
-    if (old->mins == 0) {
-      Context;
-      simple_sprintf(x, "timer%d", old->id);
+    if (!old->mins) {
+      egg_snprintf(x, sizeof x, "timer%lu", old->id);
       do_tcl(x, old->cmd);
       nfree(old->cmd);
       nfree(old);
     } else {
-      Context;
       old->next = *stack;
       *stack = old;
     }
   }
 }
 
-/* wipe all timers */
-void wipe_timers(Tcl_Interp * irp, tcl_timer_t ** stack)
+/* Wipe all timers.
+ */
+void wipe_timers(Tcl_Interp *irp, tcl_timer_t **stack)
 {
   tcl_timer_t *mark = *stack, *old;
 
@@ -601,27 +624,31 @@ void wipe_timers(Tcl_Interp * irp, tcl_timer_t ** stack)
   *stack = NULL;
 }
 
-/* return list of timers */
-void list_timers(Tcl_Interp * irp, tcl_timer_t * stack)
+/* Return list of timers
+ */
+void list_timers(Tcl_Interp *irp, tcl_timer_t *stack)
 {
-  tcl_timer_t *mark = stack;
-  char mins[10], id[20], *argv[3], *x;
-
-  while (mark != NULL) {
-    sprintf(mins, "%u", mark->mins);
-    sprintf(id, "timer%lu", mark->id);
+  tcl_timer_t *mark;
+  char mins[10], id[16], *x;
+#if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
+  CONST char *argv[3];
+#else
+  char *argv[3];
+#endif
+  for (mark = stack; mark; mark = mark->next) {
+    egg_snprintf(mins, sizeof mins, "%u", mark->mins);
+    egg_snprintf(id, sizeof id, "timer%lu", mark->id);
     argv[0] = mins;
     argv[1] = mark->cmd;
     argv[2] = id;
     x = Tcl_Merge(3, argv);
     Tcl_AppendElement(irp, x);
     Tcl_Free((char *) x);
-    mark = mark->next;
   }
 }
 
-/* Oddly enough, written by proton (Emech's coder) */
-
+/* Oddly enough, written by proton (Emech's coder)
+ */
 int isowner(char *name)
 {
   char *pa, *pb;
@@ -641,7 +668,7 @@ int isowner(char *name)
       pb++;
     }
     pl = (unsigned int) pb - (unsigned int) pa;
-    if ((pl == nl) && (!strncasecmp(pa, name, nl)))
+    if (pl == nl && !egg_strncasecmp(pa, name, nl))
       return (1);
     while (1) {
       if ((*pb == 0) || ((*pb != ',') && (*pb != ' ')))

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 247 - 245
src/cmds.c


+ 9 - 9
src/cmdt.h

@@ -1,23 +1,23 @@
-/* 
+/*
  * cmdt.h
  *   stuff for builtin commands
- * 
- * $Id: cmdt.h,v 1.4 2000/01/08 21:23:13 per Exp $
+ *
+ * $Id: cmdt.h,v 1.5 2002/01/02 03:46:35 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.

+ 92 - 0
src/compat/Makefile.in

@@ -0,0 +1,92 @@
+# Makefile for src/compat/
+# $Id: Makefile.in,v 1.5 2000/09/12 15:26:51 fabian Exp $
+
+SHELL = @SHELL@
+top_srcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+@SET_MAKE@
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+
+CC = @CC@
+LD = @CC@
+STRIP = @STRIP@
+CFLAGS = @CFLAGS@ -I../.. -I$(top_srcdir) -I$(top_srcdir)/src @DEFS@ $(CFLGS)
+CPPFLAGS = @CPPFLAGS@
+
+OBJS = inet_aton.o snprintf.o memset.o memcpy.o strcasecmp.o strftime.o
+
+doofus:
+	@echo ""
+	@echo "Let's try this from the right directory..."
+	@echo ""
+	@cd ../.. && $(MAKE)
+
+depend:
+	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/*.c > .depend
+
+clean:
+	@rm -f .depend *.o *~
+
+compat: $(OBJS)
+
+.SUFFIXES:
+.SUFFIXES: .c .o .h
+
+.c.o:
+	$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
+
+#safety hash
+gnu_strftime.o: ./gnu_strftime.c
+inet_aton.o: ./inet_aton.c ../../src/main.h ../../config.h \
+ ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
+ ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
+ ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
+ ../../src/users.h ../../src/compat/compat.h \
+ ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
+ ../../src/compat/memset.h ../../src/compat/memcpy.h \
+ ../../src/compat/strcasecmp.h ../../src/compat/strftime.h inet_aton.h
+memcpy.o: ./memcpy.c ../../src/main.h ../../config.h ../../src/lang.h \
+ ../../src/eggdrop.h ../../src/flags.h ../../src/proto.h ../../lush.h \
+ ../../src/misc_file.h ../../src/cmdt.h ../../src/tclegg.h \
+ ../../src/tclhash.h ../../src/chan.h ../../src/users.h \
+ ../../src/compat/compat.h ../../src/compat/inet_aton.h \
+ ../../src/compat/snprintf.h ../../src/compat/memset.h \
+ ../../src/compat/memcpy.h ../../src/compat/strcasecmp.h \
+ ../../src/compat/strftime.h memcpy.h
+memset.o: ./memset.c ../../src/main.h ../../config.h ../../src/lang.h \
+ ../../src/eggdrop.h ../../src/flags.h ../../src/proto.h ../../lush.h \
+ ../../src/misc_file.h ../../src/cmdt.h ../../src/tclegg.h \
+ ../../src/tclhash.h ../../src/chan.h ../../src/users.h \
+ ../../src/compat/compat.h ../../src/compat/inet_aton.h \
+ ../../src/compat/snprintf.h ../../src/compat/memset.h \
+ ../../src/compat/memcpy.h ../../src/compat/strcasecmp.h \
+ ../../src/compat/strftime.h memset.h
+snprintf.o: ./snprintf.c ../../src/main.h ../../config.h \
+ ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
+ ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
+ ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
+ ../../src/users.h ../../src/compat/compat.h \
+ ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
+ ../../src/compat/memset.h ../../src/compat/memcpy.h \
+ ../../src/compat/strcasecmp.h ../../src/compat/strftime.h snprintf.h
+strcasecmp.o: ./strcasecmp.c ../../src/main.h ../../config.h \
+ ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
+ ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
+ ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
+ ../../src/users.h ../../src/compat/compat.h \
+ ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
+ ../../src/compat/memset.h ../../src/compat/memcpy.h \
+ ../../src/compat/strcasecmp.h ../../src/compat/strftime.h memcpy.h
+strftime.o: ./strftime.c ../../src/main.h ../../config.h \
+ ../../src/lang.h ../../src/eggdrop.h ../../src/flags.h \
+ ../../src/proto.h ../../lush.h ../../src/misc_file.h ../../src/cmdt.h \
+ ../../src/tclegg.h ../../src/tclhash.h ../../src/chan.h \
+ ../../src/users.h ../../src/compat/compat.h \
+ ../../src/compat/inet_aton.h ../../src/compat/snprintf.h \
+ ../../src/compat/memset.h ../../src/compat/memcpy.h \
+ ../../src/compat/strcasecmp.h ../../src/compat/strftime.h strftime.h

+ 35 - 0
src/compat/compat.h

@@ -0,0 +1,35 @@
+/*
+ * compat.h
+ *   wrap-around header for all compability functions.
+ *
+ * $Id: compat.h,v 1.4 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_COMPAT_COMPAT_H
+#define _EGG_COMPAT_COMPAT_H
+
+#include "inet_aton.h"
+#include "snprintf.h"
+#include "memset.h"
+#include "memcpy.h"
+#include "strcasecmp.h"
+#include "strftime.h"
+
+#endif	/* !__EGG_COMPAT_COMPAT_H */

+ 1257 - 0
src/compat/gnu_strftime.c

@@ -0,0 +1,1257 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef _LIBC
+# define HAVE_LIMITS_H 1
+# define HAVE_MBLEN 1
+# define HAVE_MBRLEN 1
+# define HAVE_STRUCT_ERA_ENTRY 1
+# define HAVE_TM_GMTOFF 1
+# define HAVE_TM_ZONE 1
+# define HAVE_TZNAME 1
+# define HAVE_TZSET 1
+# define MULTIBYTE_IS_FORMAT_SAFE 1
+# define STDC_HEADERS 1
+# include "../locale/localeinfo.h"
+#endif
+
+#if defined emacs && !defined HAVE_BCOPY
+# define HAVE_MEMCPY 1
+#endif
+
+#include <ctype.h>
+#include <sys/types.h>		/* Some systems define `time_t' here.  */
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# ifdef HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+#if HAVE_TZNAME
+extern char *tzname[];
+#endif
+
+/* Do multibyte processing if multibytes are supported, unless
+   multibyte sequences are safe in formats.  Multibyte sequences are
+   safe if they cannot contain byte sequences that look like format
+   conversion specifications.  The GNU C Library uses UTF8 multibyte
+   encoding, which is safe for formats, but strftime.c can be used
+   with other C libraries that use unsafe encodings.  */
+#define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
+
+#if DO_MULTIBYTE
+# if HAVE_MBRLEN
+#  include <wchar.h>
+# else
+   /* Simulate mbrlen with mblen as best we can.  */
+#  define mbstate_t int
+#  define mbrlen(s, n, ps) mblen (s, n)
+#  define mbsinit(ps) (*(ps) == 0)
+# endif
+  static const mbstate_t mbstate_zero;
+#endif
+
+#if HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#if STDC_HEADERS
+# include <stddef.h>
+# include <stdlib.h>
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#ifdef _LIBC
+# define MEMPCPY(d, s, n) __mempcpy (d, s, n)
+#else
+# ifndef HAVE_MEMPCPY
+#  define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
+# endif
+#endif
+
+#ifndef __P
+# if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
+#  define __P(args) args
+# else
+#  define __P(args) ()
+# endif  /* GCC.  */
+#endif  /* Not __P.  */
+
+#ifndef PTR
+# ifdef __STDC__
+#  define PTR void *
+# else
+#  define PTR char *
+# endif
+#endif
+
+#ifndef CHAR_BIT
+# define CHAR_BIT 8
+#endif
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+#define TYPE_SIGNED(t) ((t) -1 < 0)
+
+/* Bound on length of the string representing an integer value of type t.
+   Subtract one for the sign bit if t is signed;
+   302 / 1000 is log10 (2) rounded up;
+   add one for integer division truncation;
+   add one more for a minus sign if t is signed.  */
+#define INT_STRLEN_BOUND(t) \
+ ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
+
+#define TM_YEAR_BASE 1900
+
+#ifndef __isleap
+/* Nonzero if YEAR is a leap year (every 4 years,
+   except every 100th isn't, and every 400th is).  */
+# define __isleap(year)	\
+  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+#endif
+
+
+#ifdef _LIBC
+# define my_strftime_gmtime_r __gmtime_r
+# define my_strftime_localtime_r __localtime_r
+# define tzname __tzname
+# define tzset __tzset
+#else
+
+/* If we're a strftime substitute in a GNU program, then prefer gmtime
+   to gmtime_r, since many gmtime_r implementations are buggy.
+   Similarly for localtime_r.  */
+
+# if ! HAVE_TM_GMTOFF
+static struct tm *my_strftime_gmtime_r __P ((const time_t *, struct tm *));
+static struct tm *
+my_strftime_gmtime_r (t, tp)
+     const time_t *t;
+     struct tm *tp;
+{
+  struct tm *l = gmtime (t);
+  if (! l)
+    return 0;
+  *tp = *l;
+  return tp;
+}
+# endif /* ! HAVE_TM_GMTOFF */
+
+static struct tm *my_strftime_localtime_r __P ((const time_t *, struct tm *));
+static struct tm *
+my_strftime_localtime_r (t, tp)
+     const time_t *t;
+     struct tm *tp;
+{
+  struct tm *l = localtime (t);
+  if (! l)
+    return 0;
+  *tp = *l;
+  return tp;
+}
+#endif /* ! defined _LIBC */
+
+
+#if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
+/* Some systems lack the `memset' function and we don't want to
+   introduce additional dependencies.  */
+/* The SGI compiler reportedly barfs on the trailing null
+   if we use a string constant as the initializer.  28 June 1997, rms.  */
+static const char spaces[16] = /* "                " */
+  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
+static const char zeroes[16] = /* "0000000000000000" */
+  { '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' };
+
+# define memset_space(P, Len) \
+  do {									      \
+    int _len = (Len);							      \
+									      \
+    do									      \
+      {									      \
+	int _this = _len > 16 ? 16 : _len;				      \
+	(P) = MEMPCPY ((P), spaces, _this);				      \
+	_len -= _this;							      \
+      }									      \
+    while (_len > 0);							      \
+  } while (0)
+
+# define memset_zero(P, Len) \
+  do {									      \
+    int _len = (Len);							      \
+									      \
+    do									      \
+      {									      \
+	int _this = _len > 16 ? 16 : _len;				      \
+	(P) = MEMPCPY ((P), zeroes, _this);				      \
+	_len -= _this;							      \
+      }									      \
+    while (_len > 0);							      \
+  } while (0)
+#else
+# define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
+# define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
+#endif
+
+#define add(n, f)							      \
+  do									      \
+    {									      \
+      int _n = (n);							      \
+      int _delta = width - _n;						      \
+      int _incr = _n + (_delta > 0 ? _delta : 0);			      \
+      if (i + _incr >= maxsize)						      \
+	return 0;							      \
+      if (p)								      \
+	{								      \
+	  if (_delta > 0)						      \
+	    {								      \
+	      if (pad == '0')						      \
+		memset_zero (p, _delta);				      \
+	      else							      \
+		memset_space (p, _delta);				      \
+	    }								      \
+	  f;								      \
+	  p += _n;							      \
+	}								      \
+      i += _incr;							      \
+    } while (0)
+
+#define cpy(n, s) \
+    add ((n),								      \
+	 if (to_lowcase)						      \
+	   memcpy_lowcase (p, (s), _n);					      \
+	 else if (to_uppcase)						      \
+	   memcpy_uppcase (p, (s), _n);					      \
+	 else								      \
+	   memcpy ((PTR) p, (PTR) (s), _n))
+
+
+
+#ifdef _LIBC
+# define TOUPPER(Ch) toupper (Ch)
+# define TOLOWER(Ch) tolower (Ch)
+#else
+# define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
+# define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
+#endif
+/* We don't use `isdigit' here since the locale dependent
+   interpretation is not what we want here.  We only need to accept
+   the arabic digits in the ASCII range.  One day there is perhaps a
+   more reliable way to accept other sets of digits.  */
+#define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9)
+
+static char *memcpy_lowcase __P ((char *dest, const char *src, size_t len));
+
+static char *
+memcpy_lowcase (dest, src, len)
+     char *dest;
+     const char *src;
+     size_t len;
+{
+  while (len-- > 0)
+    dest[len] = TOLOWER ((unsigned char) src[len]);
+  return dest;
+}
+
+static char *memcpy_uppcase __P ((char *dest, const char *src, size_t len));
+
+static char *
+memcpy_uppcase (dest, src, len)
+     char *dest;
+     const char *src;
+     size_t len;
+{
+  while (len-- > 0)
+    dest[len] = TOUPPER ((unsigned char) src[len]);
+  return dest;
+}
+
+
+#if ! HAVE_TM_GMTOFF
+/* Yield the difference between *A and *B,
+   measured in seconds, ignoring leap seconds.  */
+# define tm_diff ftime_tm_diff
+static int tm_diff __P ((const struct tm *, const struct tm *));
+static int
+tm_diff (a, b)
+     const struct tm *a;
+     const struct tm *b;
+{
+  /* Compute intervening leap days correctly even if year is negative.
+     Take care to avoid int overflow in leap day calculations,
+     but it's OK to assume that A and B are close to each other.  */
+  int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
+  int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
+  int a100 = a4 / 25 - (a4 % 25 < 0);
+  int b100 = b4 / 25 - (b4 % 25 < 0);
+  int a400 = a100 >> 2;
+  int b400 = b100 >> 2;
+  int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
+  int years = a->tm_year - b->tm_year;
+  int days = (365 * years + intervening_leap_days
+	      + (a->tm_yday - b->tm_yday));
+  return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
+		+ (a->tm_min - b->tm_min))
+	  + (a->tm_sec - b->tm_sec));
+}
+#endif /* ! HAVE_TM_GMTOFF */
+
+
+
+/* The number of days from the first day of the first ISO week of this
+   year to the year day YDAY with week day WDAY.  ISO weeks start on
+   Monday; the first ISO week has the year's first Thursday.  YDAY may
+   be as small as YDAY_MINIMUM.  */
+#define ISO_WEEK_START_WDAY 1 /* Monday */
+#define ISO_WEEK1_WDAY 4 /* Thursday */
+#define YDAY_MINIMUM (-366)
+static int iso_week_days __P ((int, int));
+#ifdef __GNUC__
+__inline__
+#endif
+static int
+iso_week_days (yday, wday)
+     int yday;
+     int wday;
+{
+  /* Add enough to the first operand of % to make it nonnegative.  */
+  int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
+  return (yday
+	  - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
+	  + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
+}
+
+
+#if !(defined _NL_CURRENT || HAVE_STRFTIME)
+static char const weekday_name[][10] =
+  {
+    "Sunday", "Monday", "Tuesday", "Wednesday",
+    "Thursday", "Friday", "Saturday"
+  };
+static char const month_name[][10] =
+  {
+    "January", "February", "March", "April", "May", "June",
+    "July", "August", "September", "October", "November", "December"
+  };
+#endif
+
+
+#ifdef emacs
+# define my_strftime emacs_strftimeu
+# define ut_argument , ut
+# define ut_argument_spec int ut;
+# define ut_argument_spec_iso , int ut
+#else
+# define my_strftime strftime
+# define ut_argument
+# define ut_argument_spec
+# define ut_argument_spec_iso
+/* We don't have this information in general.  */
+# define ut 0
+#endif
+
+#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
+  /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
+     Work around this bug by copying *tp before it might be munged.  */
+  size_t _strftime_copytm __P ((char *, size_t, const char *,
+			        const struct tm * ut_argument_spec_iso));
+  size_t
+  my_strftime (s, maxsize, format, tp ut_argument)
+      char *s;
+      size_t maxsize;
+      const char *format;
+      const struct tm *tp;
+      ut_argument_spec
+  {
+    struct tm tmcopy;
+    tmcopy = *tp;
+    return _strftime_copytm (s, maxsize, format, &tmcopy ut_argument);
+  }
+# undef my_strftime
+# define my_strftime(S, Maxsize, Format, Tp) \
+  _strftime_copytm (S, Maxsize, Format, Tp)
+#endif
+
+
+/* Write information from TP into S according to the format
+   string FORMAT, writing no more that MAXSIZE characters
+   (including the terminating '\0') and returning number of
+   characters written.  If S is NULL, nothing will be written
+   anywhere, so to determine how many characters would be
+   written, use NULL for S and (size_t) UINT_MAX for MAXSIZE.  */
+size_t
+my_strftime (s, maxsize, format, tp ut_argument)
+      char *s;
+      size_t maxsize;
+      const char *format;
+      const struct tm *tp;
+      ut_argument_spec
+{
+  int hour12 = tp->tm_hour;
+#ifdef _NL_CURRENT
+  /* We cannot make the following values variables since we must delay
+     the evaluation of these values until really needed since some
+     expressions might not be valid in every situation.  The `struct tm'
+     might be generated by a strptime() call that initialized
+     only a few elements.  Dereference the pointers only if the format
+     requires this.  Then it is ok to fail if the pointers are invalid.  */
+# define a_wkday _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday)
+# define f_wkday _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday)
+# define a_month _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon)
+# define f_month _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon)
+# define ampm _NL_CURRENT (LC_TIME, tp->tm_hour > 11 ? PM_STR : AM_STR)
+
+# define aw_len strlen (a_wkday)
+# define am_len strlen (a_month)
+# define ap_len strlen (ampm)
+#else
+# if !HAVE_STRFTIME
+# define f_wkday (weekday_name[tp->tm_wday])
+# define f_month (month_name[tp->tm_mon])
+# define a_wkday f_wkday
+# define a_month f_month
+# define ampm ("AMPM" + 2 * (tp->tm_hour > 11))
+
+  size_t aw_len = 3;
+  size_t am_len = 3;
+  size_t ap_len = 2;
+# endif
+#endif
+  const char *zone;
+  size_t i = 0;
+  char *p = s;
+  const char *f;
+
+  zone = NULL;
+#if HAVE_TM_ZONE
+  /* The POSIX test suite assumes that setting
+     the environment variable TZ to a new value before calling strftime()
+     will influence the result (the %Z format) even if the information in
+     TP is computed with a totally different time zone.
+     This is bogus: though POSIX allows bad behavior like this,
+     POSIX does not require it.  Do the right thing instead.  */
+  zone = (const char *) tp->tm_zone;
+#endif
+#if HAVE_TZNAME
+  if (ut)
+    {
+      if (! (zone && *zone))
+	zone = "GMT";
+    }
+  else
+    {
+      /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
+	 time zone names contained in the external variable `tzname' shall
+	 be set as if the tzset() function had been called.  */
+# if HAVE_TZSET
+      tzset ();
+# endif
+    }
+#endif
+
+  if (hour12 > 12)
+    hour12 -= 12;
+  else
+    if (hour12 == 0)
+      hour12 = 12;
+
+  for (f = format; *f != '\0'; ++f)
+    {
+      int pad = 0;		/* Padding for number ('-', '_', or 0).  */
+      int modifier;		/* Field modifier ('E', 'O', or 0).  */
+      int digits;		/* Max digits for numeric format.  */
+      int number_value; 	/* Numeric value to be printed.  */
+      int negative_number;	/* 1 if the number is negative.  */
+      const char *subfmt;
+      char *bufp;
+      char buf[1 + (sizeof (int) < sizeof (time_t)
+		    ? INT_STRLEN_BOUND (time_t)
+		    : INT_STRLEN_BOUND (int))];
+      int width = -1;
+      int to_lowcase = 0;
+      int to_uppcase = 0;
+      int change_case = 0;
+      int format_char;
+
+#if DO_MULTIBYTE
+
+       switch (*f)
+	{
+	case '%':
+	  break;
+
+	case '\a': case '\b': case '\t': case '\n':
+	case '\v': case '\f': case '\r':
+	case ' ': case '!': case '"': case '#': case '&': case'\'':
+	case '(': case ')': case '*': case '+': case ',': case '-':
+	case '.': case '/': case '0': case '1': case '2': case '3':
+	case '4': case '5': case '6': case '7': case '8': case '9':
+	case ':': case ';': case '<': case '=': case '>': case '?':
+	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+	case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+	case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+	case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+	case 'Y': case 'Z': case '[': case'\\': case ']': case '^':
+	case '_': case 'a': case 'b': case 'c': case 'd': case 'e':
+	case 'f': case 'g': case 'h': case 'i': case 'j': case 'k':
+	case 'l': case 'm': case 'n': case 'o': case 'p': case 'q':
+	case 'r': case 's': case 't': case 'u': case 'v': case 'w':
+	case 'x': case 'y': case 'z': case '{': case '|': case '}':
+	case '~':
+	  /* The C Standard requires these 98 characters (plus '%') to
+	     be in the basic execution character set.  None of these
+	     characters can start a multibyte sequence, so they need
+	     not be analyzed further.  */
+	  add (1, *p = *f);
+	  continue;
+
+	default:
+	  /* Copy this multibyte sequence until we reach its end, find
+	     an error, or come back to the initial shift state.  */
+	  {
+	    mbstate_t mbstate = mbstate_zero;
+	    size_t len = 0;
+
+	    do
+	      {
+		size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate);
+
+		if (bytes == 0)
+		  break;
+
+		if (bytes == (size_t) -2)
+		  {
+		    len += strlen (f + len);
+		    break;
+		  }
+
+		if (bytes == (size_t) -1)
+		  {
+		    len++;
+		    break;
+		  }
+
+		len += bytes;
+	      }
+	    while (! mbsinit (&mbstate));
+
+	    cpy (len, f);
+	    f += len - 1;
+	    continue;
+	  }
+	}
+
+#else /* ! DO_MULTIBYTE */
+
+      /* Either multibyte encodings are not supported, or they are
+	 safe for formats, so any non-'%' byte can be copied through.  */
+      if (*f != '%')
+	{
+	  add (1, *p = *f);
+	  continue;
+	}
+
+#endif /* ! DO_MULTIBYTE */
+
+      /* Check for flags that can modify a format.  */
+      while (1)
+	{
+	  switch (*++f)
+	    {
+	      /* This influences the number formats.  */
+	    case '_':
+	    case '-':
+	    case '0':
+	      pad = *f;
+	      continue;
+
+	      /* This changes textual output.  */
+	    case '^':
+	      to_uppcase = 1;
+	      continue;
+	    case '#':
+	      change_case = 1;
+	      continue;
+
+	    default:
+	      break;
+	    }
+	  break;
+	}
+
+      /* As a GNU extension we allow to specify the field width.  */
+      if (ISDIGIT (*f))
+	{
+	  width = 0;
+	  do
+	    {
+	      width *= 10;
+	      width += *f - '0';
+	      ++f;
+	    }
+	  while (ISDIGIT (*f));
+	}
+
+      /* Check for modifiers.  */
+      switch (*f)
+	{
+	case 'E':
+	case 'O':
+	  modifier = *f++;
+	  break;
+
+	default:
+	  modifier = 0;
+	  break;
+	}
+
+      /* Now do the specified format.  */
+      format_char = *f;
+      switch (format_char)
+	{
+#define DO_NUMBER(d, v) \
+	  digits = width == -1 ? d : width;				      \
+	  number_value = v; goto do_number
+#define DO_NUMBER_SPACEPAD(d, v) \
+	  digits = width == -1 ? d : width;				      \
+	  number_value = v; goto do_number_spacepad
+
+	case '%':
+	  if (modifier != 0)
+	    goto bad_format;
+	  add (1, *p = *f);
+	  break;
+
+	case 'a':
+	  if (modifier != 0)
+	    goto bad_format;
+	  if (change_case)
+	    {
+	      to_uppcase = 1;
+	      to_lowcase = 0;
+	    }
+#if defined _NL_CURRENT || !HAVE_STRFTIME
+	  cpy (aw_len, a_wkday);
+	  break;
+#else
+	  goto underlying_strftime;
+#endif
+
+	case 'A':
+	  if (modifier != 0)
+	    goto bad_format;
+	  if (change_case)
+	    {
+	      to_uppcase = 1;
+	      to_lowcase = 0;
+	    }
+#if defined _NL_CURRENT || !HAVE_STRFTIME
+	  cpy (strlen (f_wkday), f_wkday);
+	  break;
+#else
+	  goto underlying_strftime;
+#endif
+
+	case 'b':
+	case 'h':		/* POSIX.2 extension.  */
+	  if (modifier != 0)
+	    goto bad_format;
+#if defined _NL_CURRENT || !HAVE_STRFTIME
+	  cpy (am_len, a_month);
+	  break;
+#else
+	  goto underlying_strftime;
+#endif
+
+	case 'B':
+	  if (modifier != 0)
+	    goto bad_format;
+	  if (change_case)
+	    {
+	      to_uppcase = 1;
+	      to_lowcase = 0;
+	    }
+#if defined _NL_CURRENT || !HAVE_STRFTIME
+	  cpy (strlen (f_month), f_month);
+	  break;
+#else
+	  goto underlying_strftime;
+#endif
+
+	case 'c':
+	  if (modifier == 'O')
+	    goto bad_format;
+#ifdef _NL_CURRENT
+	  if (! (modifier == 'E'
+		 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0'))
+	    subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
+#else
+# if HAVE_STRFTIME
+	  goto underlying_strftime;
+# else
+	  subfmt = "%a %b %e %H:%M:%S %Y";
+# endif
+#endif
+
+	subformat:
+	  {
+	    char *old_start = p;
+	    size_t len = my_strftime (NULL, (size_t) -1, subfmt, tp);
+	    add (len, my_strftime (p, maxsize - i, subfmt, tp));
+
+	    if (to_uppcase)
+	      while (old_start < p)
+		{
+		  *old_start = TOUPPER ((unsigned char) *old_start);
+		  ++old_start;
+		}
+	  }
+	  break;
+
+#if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
+	underlying_strftime:
+	  {
+	    /* The relevant information is available only via the
+	       underlying strftime implementation, so use that.  */
+	    char ufmt[4];
+	    char *u = ufmt;
+	    char ubuf[1024]; /* enough for any single format in practice */
+	    size_t len;
+	    *u++ = '%';
+	    if (modifier != 0)
+	      *u++ = modifier;
+	    *u++ = format_char;
+	    *u = '\0';
+	    len = strftime (ubuf, sizeof ubuf, ufmt, tp);
+	    if (len == 0 && ubuf[0] != '\0')
+	      return 0;
+	    cpy (len, ubuf);
+	  }
+	  break;
+#endif
+
+	case 'C':		/* POSIX.2 extension.  */
+	  if (modifier == 'O')
+	    goto bad_format;
+	  if (modifier == 'E')
+	    {
+#if HAVE_STRUCT_ERA_ENTRY
+	      struct era_entry *era = _nl_get_era_entry (tp);
+	      if (era)
+		{
+		  size_t len = strlen (era->name_fmt);
+		  cpy (len, era->name_fmt);
+		  break;
+		}
+#else
+# if HAVE_STRFTIME
+	      goto underlying_strftime;
+# endif
+#endif
+	    }
+
+	  {
+	    int year = tp->tm_year + TM_YEAR_BASE;
+	    DO_NUMBER (1, year / 100 - (year % 100 < 0));
+	  }
+
+	case 'x':
+	  if (modifier == 'O')
+	    goto bad_format;
+#ifdef _NL_CURRENT
+	  if (! (modifier == 'E'
+		 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0'))
+	    subfmt = _NL_CURRENT (LC_TIME, D_FMT);
+	  goto subformat;
+#else
+# if HAVE_STRFTIME
+	  goto underlying_strftime;
+# else
+	  /* Fall through.  */
+# endif
+#endif
+	case 'D':		/* POSIX.2 extension.  */
+	  if (modifier != 0)
+	    goto bad_format;
+	  subfmt = "%m/%d/%y";
+	  goto subformat;
+
+	case 'd':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, tp->tm_mday);
+
+	case 'e':		/* POSIX.2 extension.  */
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER_SPACEPAD (2, tp->tm_mday);
+
+	  /* All numeric formats set DIGITS and NUMBER_VALUE and then
+	     jump to one of these two labels.  */
+
+	do_number_spacepad:
+	  /* Force `_' flag unless overwritten by `0' flag.  */
+	  if (pad != '0')
+	    pad = '_';
+
+	do_number:
+	  /* Format the number according to the MODIFIER flag.  */
+
+	  if (modifier == 'O' && 0 <= number_value)
+	    {
+#ifdef _NL_CURRENT
+	      /* Get the locale specific alternate representation of
+		 the number NUMBER_VALUE.  If none exist NULL is returned.  */
+	      const char *cp = _nl_get_alt_digit (number_value);
+
+	      if (cp != NULL)
+		{
+		  size_t digitlen = strlen (cp);
+		  if (digitlen != 0)
+		    {
+		      cpy (digitlen, cp);
+		      break;
+		    }
+		}
+#else
+# if HAVE_STRFTIME
+	      goto underlying_strftime;
+# endif
+#endif
+	    }
+	  {
+	    unsigned int u = number_value;
+
+	    bufp = buf + sizeof (buf);
+	    negative_number = number_value < 0;
+
+	    if (negative_number)
+	      u = -u;
+
+	    do
+	      *--bufp = u % 10 + '0';
+	    while ((u /= 10) != 0);
+  	  }
+
+	do_number_sign_and_padding:
+	  if (negative_number)
+	    *--bufp = '-';
+
+	  if (pad != '-')
+	    {
+	      int padding = digits - (buf + sizeof (buf) - bufp);
+
+	      if (pad == '_')
+		{
+		  while (0 < padding--)
+		    *--bufp = ' ';
+		}
+	      else
+		{
+		  bufp += negative_number;
+		  while (0 < padding--)
+		    *--bufp = '0';
+		  if (negative_number)
+		    *--bufp = '-';
+		}
+	    }
+
+	  cpy (buf + sizeof (buf) - bufp, bufp);
+	  break;
+
+	case 'F':
+	  if (modifier != 0)
+	    goto bad_format;
+	  subfmt = "%Y-%m-%d";
+	  goto subformat;
+
+	case 'H':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, tp->tm_hour);
+
+	case 'I':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, hour12);
+
+	case 'k':		/* GNU extension.  */
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER_SPACEPAD (2, tp->tm_hour);
+
+	case 'l':		/* GNU extension.  */
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER_SPACEPAD (2, hour12);
+
+	case 'j':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (3, 1 + tp->tm_yday);
+
+	case 'M':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, tp->tm_min);
+
+	case 'm':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, tp->tm_mon + 1);
+
+	case 'n':		/* POSIX.2 extension.  */
+	  add (1, *p = '\n');
+	  break;
+
+	case 'P':
+	  to_lowcase = 1;
+#if !defined _NL_CURRENT && HAVE_STRFTIME
+	  format_char = 'p';
+#endif
+	  /* FALLTHROUGH */
+
+	case 'p':
+	  if (change_case)
+	    {
+	      to_uppcase = 0;
+	      to_lowcase = 1;
+	    }
+#if defined _NL_CURRENT || !HAVE_STRFTIME
+	  cpy (ap_len, ampm);
+	  break;
+#else
+	  goto underlying_strftime;
+#endif
+
+	case 'R':		/* GNU extension.  */
+	  subfmt = "%H:%M";
+	  goto subformat;
+
+	case 'r':		/* POSIX.2 extension.  */
+#ifdef _NL_CURRENT
+	  if (*(subfmt = _NL_CURRENT (LC_TIME, T_FMT_AMPM)) == '\0')
+#endif
+	    subfmt = "%I:%M:%S %p";
+	  goto subformat;
+
+	case 'S':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, tp->tm_sec);
+
+	case 's':		/* GNU extension.  */
+  	  {
+	    struct tm ltm;
+	    time_t t;
+
+	    ltm = *tp;
+	    t = mktime (&ltm);
+
+	    /* Generate string value for T using time_t arithmetic;
+	       this works even if sizeof (long) < sizeof (time_t).  */
+
+	    bufp = buf + sizeof (buf);
+	    negative_number = t < 0;
+
+	    do
+	      {
+		int d = t % 10;
+		t /= 10;
+
+		if (negative_number)
+		  {
+		    d = -d;
+
+		    /* Adjust if division truncates to minus infinity.  */
+		    if (0 < -1 % 10 && d < 0)
+		      {
+			t++;
+			d += 10;
+		      }
+		  }
+
+		*--bufp = d + '0';
+	      }
+	    while (t != 0);
+
+	    digits = 1;
+	    goto do_number_sign_and_padding;
+	  }
+
+	case 'X':
+	  if (modifier == 'O')
+	    goto bad_format;
+#ifdef _NL_CURRENT
+	  if (! (modifier == 'E'
+		 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0'))
+	    subfmt = _NL_CURRENT (LC_TIME, T_FMT);
+	  goto subformat;
+#else
+# if HAVE_STRFTIME
+	  goto underlying_strftime;
+# else
+	  /* Fall through.  */
+# endif
+#endif
+	case 'T':		/* POSIX.2 extension.  */
+	  subfmt = "%H:%M:%S";
+	  goto subformat;
+
+	case 't':		/* POSIX.2 extension.  */
+	  add (1, *p = '\t');
+	  break;
+
+	case 'u':		/* POSIX.2 extension.  */
+	  DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
+
+	case 'U':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
+
+	case 'V':
+	case 'g':		/* GNU extension.  */
+	case 'G':		/* GNU extension.  */
+	  if (modifier == 'E')
+	    goto bad_format;
+	  {
+	    int year = tp->tm_year + TM_YEAR_BASE;
+	    int days = iso_week_days (tp->tm_yday, tp->tm_wday);
+
+	    if (days < 0)
+	      {
+		/* This ISO week belongs to the previous year.  */
+		year--;
+		days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
+				      tp->tm_wday);
+	      }
+	    else
+	      {
+		int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
+				       tp->tm_wday);
+		if (0 <= d)
+		  {
+		    /* This ISO week belongs to the next year.  */
+		    year++;
+		    days = d;
+		  }
+	      }
+
+	    switch (*f)
+	      {
+	      case 'g':
+		DO_NUMBER (2, (year % 100 + 100) % 100);
+
+	      case 'G':
+		DO_NUMBER (1, year);
+
+	      default:
+		DO_NUMBER (2, days / 7 + 1);
+	      }
+	  }
+
+	case 'W':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
+
+	case 'w':
+	  if (modifier == 'E')
+	    goto bad_format;
+
+	  DO_NUMBER (1, tp->tm_wday);
+
+	case 'Y':
+	  if (modifier == 'E')
+	    {
+#if HAVE_STRUCT_ERA_ENTRY
+	      struct era_entry *era = _nl_get_era_entry (tp);
+	      if (era)
+		{
+		  subfmt = strchr (era->name_fmt, '\0') + 1;
+		  goto subformat;
+		}
+#else
+# if HAVE_STRFTIME
+	      goto underlying_strftime;
+# endif
+#endif
+	    }
+	  if (modifier == 'O')
+	    goto bad_format;
+	  else
+	    DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
+
+	case 'y':
+	  if (modifier == 'E')
+	    {
+#if HAVE_STRUCT_ERA_ENTRY
+	      struct era_entry *era = _nl_get_era_entry (tp);
+	      if (era)
+		{
+		  int delta = tp->tm_year - era->start_date[0];
+		  DO_NUMBER (1, (era->offset
+				 + (era->direction == '-' ? -delta : delta)));
+		}
+#else
+# if HAVE_STRFTIME
+	      goto underlying_strftime;
+# endif
+#endif
+	    }
+	  DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
+
+	case 'Z':
+	  if (change_case)
+	    {
+	      to_uppcase = 0;
+	      to_lowcase = 1;
+	    }
+
+#if HAVE_TZNAME
+	  /* The tzset() call might have changed the value.  */
+	  if (!(zone && *zone) && tp->tm_isdst >= 0)
+	    zone = tzname[tp->tm_isdst];
+#endif
+	  if (! zone)
+	    zone = "";		/* POSIX.2 requires the empty string here.  */
+
+	  cpy (strlen (zone), zone);
+	  break;
+
+	case 'z':		/* GNU extension.  */
+	  if (tp->tm_isdst < 0)
+	    break;
+
+	  {
+	    int diff;
+#if HAVE_TM_GMTOFF
+	    diff = tp->tm_gmtoff;
+#else
+	    if (ut)
+	      diff = 0;
+	    else
+	      {
+		struct tm gtm;
+		struct tm ltm;
+		time_t lt;
+
+		ltm = *tp;
+		lt = mktime (&ltm);
+
+		if (lt == (time_t) -1)
+		  {
+		    /* mktime returns -1 for errors, but -1 is also a
+		       valid time_t value.  Check whether an error really
+		       occurred.  */
+		    struct tm tm;
+
+		    if (! my_strftime_localtime_r (&lt, &tm)
+			|| ((ltm.tm_sec ^ tm.tm_sec)
+			    | (ltm.tm_min ^ tm.tm_min)
+			    | (ltm.tm_hour ^ tm.tm_hour)
+			    | (ltm.tm_mday ^ tm.tm_mday)
+			    | (ltm.tm_mon ^ tm.tm_mon)
+			    | (ltm.tm_year ^ tm.tm_year)))
+		      break;
+		  }
+
+		if (! my_strftime_gmtime_r (&lt, &gtm))
+		  break;
+
+		diff = tm_diff (&ltm, &gtm);
+	      }
+#endif
+
+	    if (diff < 0)
+	      {
+		add (1, *p = '-');
+		diff = -diff;
+	      }
+	    else
+	      add (1, *p = '+');
+
+	    diff /= 60;
+	    DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
+	  }
+
+	case '\0':		/* GNU extension: % at end of format.  */
+	    --f;
+	    /* Fall through.  */
+	default:
+	  /* Unknown format; output the format, including the '%',
+	     since this is most likely the right thing to do if a
+	     multibyte string has been misparsed.  */
+	bad_format:
+	  {
+	    int flen;
+	    for (flen = 1; f[1 - flen] != '%'; flen++)
+	      continue;
+	    cpy (flen, &f[1 - flen]);
+	  }
+	  break;
+	}
+    }
+
+  if (p && maxsize != 0)
+    *p = '\0';
+  return i;
+}
+
+
+#ifdef emacs
+/* For Emacs we have a separate interface which corresponds to the normal
+   strftime function and does not have the extra information whether the
+   TP arguments comes from a `gmtime' call or not.  */
+size_t
+emacs_strftime (s, maxsize, format, tp)
+      char *s;
+      size_t maxsize;
+      const char *format;
+      const struct tm *tp;
+{
+  return my_strftime (s, maxsize, format, tp, 0);
+}
+#endif

+ 186 - 0
src/compat/inet_aton.c

@@ -0,0 +1,186 @@
+/*
+ * inet_aton.c -- provides inet_aton() if necessary.
+ *
+ * $Id: inet_aton.c,v 1.7 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Portions Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 "main.h"
+#include "inet_aton.h"
+
+#ifndef HAVE_ISASCII
+/* Let all checks succeed if we don't have isascii(). */
+#  define isascii(x)	1
+#endif
+
+#ifndef HAVE_INET_ATON
+/*
+ * ++Copyright++ 1983, 1990, 1993
+ * -
+ * Copyright (c) 1983, 1990, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_addr.c	8.1 (Berkeley) 6/17/93";
+static char rcsid[] = "$-Id: inet_addr.c,v 1.11 1999/04/29 18:19:53 drepper Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <ctype.h>
+
+/*
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+int
+egg_inet_aton(cp, addr)
+	const char *cp;
+	struct in_addr *addr;
+{
+	static const u_32bit_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
+	register u_32bit_t val;	/* changed from u_long --david */
+	register int base;
+	register int n;
+	register char c;
+	u_32bit_t parts[4];
+	register u_32bit_t *pp = parts;
+
+	egg_bzero(parts, sizeof (parts));
+
+	c = *cp;
+	for (;;) {
+		/*
+		 * Collect number up to ``.''.
+		 * Values are specified as for C:
+		 * 0x=hex, 0=octal, isdigit=decimal.
+		 */
+		if (!isdigit(c))
+			goto ret_0;
+		base = 10;
+		if (c == '0') {
+			c = *++cp;
+			if (c == 'x' || c == 'X')
+				base = 16, c = *++cp;
+			else
+				base = 8;
+		}
+		val = 0;
+		for (;;) {
+			if (isascii(c) && isdigit(c)) {
+				val = (val * base) + (c - '0');
+				c = *++cp;
+			} else if (base == 16 && isascii(c) && isxdigit(c)) {
+				val = (val << 4) |
+					(c + 10 - (islower(c) ? 'a' : 'A'));
+				c = *++cp;
+			} else
+				break;
+		}
+		if (c == '.') {
+			/*
+			 * Internet format:
+			 *	a.b.c.d
+			 *	a.b.c	(with c treated as 16 bits)
+			 *	a.b	(with b treated as 24 bits)
+			 */
+			if (pp >= parts + 3)
+				goto ret_0;
+			*pp++ = val;
+			c = *++cp;
+		} else
+			break;
+	}
+	/*
+	 * Check for trailing characters.
+	 */
+	if (c != '\0' && (!isascii(c) || !isspace(c)))
+		goto ret_0;
+	/*
+	 * Concoct the address according to
+	 * the number of parts specified.
+	 */
+	n = pp - parts + 1;
+
+	if (n == 0	/* initial nondigit */
+	    || parts[0] > 0xff || parts[1] > 0xff || parts[2] > 0xff
+	    || val > max[n - 1])
+	  goto ret_0;
+
+	val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+
+	if (addr)
+		addr->s_addr = htonl(val);
+	return (1);
+
+ret_0:
+	return (0);
+}
+#endif /* HAVE_INET_ATON */

+ 40 - 0
src/compat/inet_aton.h

@@ -0,0 +1,40 @@
+/*
+ * inet_aton.h
+ *   prototypes for inet_aton.c
+ *
+ * $Id: inet_aton.h,v 1.4 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_COMPAT_INET_ATON_H
+#define _EGG_COMPAT_INET_ATON_H
+
+#include "src/main.h"
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifndef HAVE_INET_ATON
+/* Use our own implementation. */
+int egg_inet_aton(const char *cp, struct in_addr *addr);
+#else
+#  define egg_inet_aton	inet_aton
+#endif
+
+#endif	/* !__EGG_COMPAT_INET_ATON_H */

+ 35 - 0
src/compat/memcpy.c

@@ -0,0 +1,35 @@
+/*
+ * memcpy.c -- provides memcpy() if necessary.
+ *
+ * $Id: memcpy.c,v 1.3 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 "main.h"
+#include "memcpy.h"
+
+#ifndef HAVE_MEMCPY
+void *egg_memcpy(void *dest, const void *src, size_t n)
+{
+  while (n--)
+    *((char *) dest)++ = *((char *) src)++;
+  return dest;
+}
+#endif /* !HAVE_MEMCPY */

+ 38 - 0
src/compat/memcpy.h

@@ -0,0 +1,38 @@
+/*
+ * memcpy.h
+ *   prototypes for memcpy.c
+ *
+ * $Id: memcpy.h,v 1.4 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_COMPAT_MEMCPY_H
+#define _EGG_COMPAT_MEMCPY_H
+
+#include "src/main.h"
+#include <string.h>
+
+#ifndef HAVE_MEMCPY
+/* Use our own implementation. */
+void *egg_memcpy(void *dest, const void *src, size_t n);
+#else
+#  define egg_memcpy	memcpy
+#endif
+
+#endif	/* !__EGG_COMPAT_MEMCPY_H */

+ 35 - 0
src/compat/memset.c

@@ -0,0 +1,35 @@
+/*
+ * memset.c -- provides memset() if necessary.
+ *
+ * $Id: memset.c,v 1.4 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 "main.h"
+#include "memset.h"
+
+#ifndef HAVE_MEMSET
+void *egg_memset(void *dest, int c, size_t n)
+{
+  while (n--)
+    *((u_8bit_t *) dest)++ = c;
+  return dest;
+}
+#endif /* !HAVE_MEMSET */

+ 42 - 0
src/compat/memset.h

@@ -0,0 +1,42 @@
+/*
+ * memset.h
+ *   prototypes for memset.c
+ *
+ * $Id: memset.h,v 1.4 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_COMPAT_MEMSET_H
+#define _EGG_COMPAT_MEMSET_H
+
+#include "src/main.h"
+#include <string.h>
+
+#ifndef HAVE_MEMSET
+/* Use our own implementation. */
+void *egg_memset(void *dest, int c, size_t n);
+#else
+#  define egg_memset	memset
+#endif
+
+/* Use memset instead of bzero.
+ */
+#define egg_bzero(dest, n)	egg_memset(dest, 0, n)
+
+#endif	/* !__EGG_COMPAT_MEMSET_H */

+ 721 - 0
src/compat/snprintf.c

@@ -0,0 +1,721 @@
+ * snprintf.c - a portable implementation of snprintf and vsnprintf
+ *
+ * $Id: snprintf.c,v 1.6 2002/07/18 20:28:32 guppy Exp $
+ */
+/*
+ * Portions Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 "main.h"
+#include "snprintf.h"
+
+
+/*
+ * Copyright Patrick Powell 1995
+ * This code is based on code written by Patrick Powell (papowell@astart.com)
+ * It may be used for any purpose as long as this notice remains intact
+ * on all source code distributions
+ */
+
+/**************************************************************
+ * Original:
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
+ * A bombproof version of doprnt (dopr) included.
+ * Sigh.  This sort of thing is always nasty do deal with.  Note that
+ * the version here does not include floating point...
+ *
+ * snprintf() is used instead of sprintf() as it does limit checks
+ * for string length.  This covers a nasty loophole.
+ *
+ * The other functions are there to prevent NULL pointers from
+ * causing nast effects.
+ *
+ * More Recently:
+ *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
+ *  This was ugly.  It is still ugly.  I opted out of floating point
+ *  numbers, but the formatter understands just about everything
+ *  from the normal C string format, at least as far as I can tell from
+ *  the Solaris 2.5 printf(3S) man page.
+ *
+ *  Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
+ *    Ok, added some minimal floating point support, which means this
+ *    probably requires libm on most operating systems.  Don't yet
+ *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
+ *    was pretty badly broken, it just wasn't being exercised in ways
+ *    which showed it, so that's been fixed.  Also, formated the code
+ *    to mutt conventions, and removed dead code left over from the
+ *    original.  Also, there is now a builtin-test, just compile with:
+ *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
+ *    and run snprintf for results.
+ *
+ *  Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
+ *    The PGP code was using unsigned hexadecimal formats.
+ *    Unfortunately, unsigned formats simply didn't work.
+ *
+ *  Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
+ *    The original code assumed that both snprintf() and vsnprintf() were
+ *    missing.  Some systems only have snprintf() but not vsnprintf(), so
+ *    the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
+ *
+ *  Andrew Tridgell (tridge@samba.org) Oct 1998
+ *    fixed handling of %.0f
+ *    added test for HAVE_LONG_DOUBLE
+ *
+ *  Fabian Knittel <fknittel@gmx.de> Apr 2000 for eggdrop 1.5.3
+ *    Indented code to match eggdrop style. Adjusted to fit into eggdrops
+ *    build environment. Added `egg_' prefixes to snprintf and vsnprintf.
+ *
+ **************************************************************/
+
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+
+#ifndef HAVE_VSNPRINTF
+
+/* varargs declarations: */
+
+#if defined(__STDC__)
+#  ifdef HAVE_STDARG_H
+#    include <stdarg.h>
+#  else
+#    ifdef HAVE_STD_ARGS_H
+#      include <std_args.h>
+#    endif
+#  endif
+#  define HAVE_STDARGS		/* let's hope that works everywhere (mj) */
+#  define VA_LOCAL_DECL	va_list ap
+#  define VA_START(f)	va_start(ap, f)
+#  define VA_SHIFT(v,t)	;	/* no-op for ANSI */
+#  define VA_END	va_end(ap)
+#else
+#  include <varargs.h>
+#  undef HAVE_STDARGS
+#  define VA_LOCAL_DECL	va_list ap
+#  define VA_START(f)	va_start(ap)	/* f is ignored! */
+#  define VA_SHIFT(v,t)	v = va_arg(ap,t)
+#  define VA_END	va_end(ap)
+#endif
+
+#ifdef HAVE_LONG_DOUBLE
+#define LDOUBLE	long double
+#else
+#define LDOUBLE	double
+#endif
+
+static void dopr(char *buffer, size_t maxlen, const char *format,
+		 va_list args);
+static void fmtstr(char *buffer, size_t * currlen, size_t maxlen,
+		   char *value, int flags, int min, int max);
+static void fmtint(char *buffer, size_t * currlen, size_t maxlen,
+		   long value, int base, int min, int max, int flags);
+static void fmtfp(char *buffer, size_t * currlen, size_t maxlen,
+		  LDOUBLE fvalue, int min, int max, int flags);
+static void dopr_outch(char *buffer, size_t * currlen, size_t maxlen,
+		       char c);
+
+/*
+ * dopr(): poor man's version of doprintf
+ */
+
+/* format read states */
+#define DP_S_DEFAULT 0
+#define DP_S_FLAGS   1
+#define DP_S_MIN     2
+#define DP_S_DOT     3
+#define DP_S_MAX     4
+#define DP_S_MOD     5
+#define DP_S_CONV    6
+#define DP_S_DONE    7
+
+/* format flags - Bits */
+#define DP_F_MINUS 	(1 << 0)
+#define DP_F_PLUS  	(1 << 1)
+#define DP_F_SPACE 	(1 << 2)
+#define DP_F_NUM   	(1 << 3)
+#define DP_F_ZERO  	(1 << 4)
+#define DP_F_UP    	(1 << 5)
+#define DP_F_UNSIGNED 	(1 << 6)
+
+/* Conversion Flags */
+#define DP_C_SHORT   1
+#define DP_C_LONG    2
+#define DP_C_LDOUBLE 3
+
+#define char_to_int(p) (p - '0')
+#define MAX(p,q) ((p >= q) ? p : q)
+
+static void dopr(char *buffer, size_t maxlen, const char *format,
+		 va_list args)
+{
+  char ch;
+  long value;
+  LDOUBLE fvalue;
+  char *strvalue;
+  int min;
+  int max;
+  int state;
+  int flags;
+  int cflags;
+  size_t currlen;
+
+  state = DP_S_DEFAULT;
+  currlen = flags = cflags = min = 0;
+  max = -1;
+  ch = *format++;
+
+  while (state != DP_S_DONE) {
+    if ((ch == '\0') || (currlen >= maxlen))
+      state = DP_S_DONE;
+
+    switch (state) {
+    case DP_S_DEFAULT:
+      if (ch == '%')
+	state = DP_S_FLAGS;
+      else
+	dopr_outch(buffer, &currlen, maxlen, ch);
+      ch = *format++;
+      break;
+    case DP_S_FLAGS:
+      switch (ch) {
+      case '-':
+	flags |= DP_F_MINUS;
+	ch = *format++;
+	break;
+      case '+':
+	flags |= DP_F_PLUS;
+	ch = *format++;
+	break;
+      case ' ':
+	flags |= DP_F_SPACE;
+	ch = *format++;
+	break;
+      case '#':
+	flags |= DP_F_NUM;
+	ch = *format++;
+	break;
+      case '0':
+	flags |= DP_F_ZERO;
+	ch = *format++;
+	break;
+      default:
+	state = DP_S_MIN;
+	break;
+      }
+      break;
+    case DP_S_MIN:
+      if (isdigit(ch)) {
+	min = 10 * min + char_to_int(ch);
+	ch = *format++;
+      } else if (ch == '*') {
+	min = va_arg(args, int);
+	ch = *format++;
+	state = DP_S_DOT;
+      } else
+	state = DP_S_DOT;
+      break;
+    case DP_S_DOT:
+      if (ch == '.') {
+	state = DP_S_MAX;
+	ch = *format++;
+      } else
+	state = DP_S_MOD;
+      break;
+    case DP_S_MAX:
+      if (isdigit(ch)) {
+	if (max < 0)
+	  max = 0;
+	max = 10 * max + char_to_int(ch);
+	ch = *format++;
+      } else if (ch == '*') {
+	max = va_arg(args, int);
+	ch = *format++;
+	state = DP_S_MOD;
+      } else
+	state = DP_S_MOD;
+      break;
+    case DP_S_MOD:
+      /* Currently, we don't support Long Long, bummer */
+      switch (ch) {
+      case 'h':
+	cflags = DP_C_SHORT;
+	ch = *format++;
+	break;
+      case 'l':
+	cflags = DP_C_LONG;
+	ch = *format++;
+	break;
+      case 'L':
+	cflags = DP_C_LDOUBLE;
+	ch = *format++;
+	break;
+      default:
+	break;
+      }
+      state = DP_S_CONV;
+      break;
+    case DP_S_CONV:
+      switch (ch) {
+      case 'd':
+      case 'i':
+	if (cflags == DP_C_SHORT)
+	  value = va_arg(args, short int);
+	else if (cflags == DP_C_LONG)
+	  value = va_arg(args, long int);
+	else
+	  value = va_arg(args, int);
+	fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
+	break;
+      case 'o':
+	flags |= DP_F_UNSIGNED;
+	if (cflags == DP_C_SHORT)
+	  value = va_arg(args, unsigned short int);
+	else if (cflags == DP_C_LONG)
+	  value = va_arg(args, unsigned long int);
+	else
+	  value = va_arg(args, unsigned int);
+	fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags);
+	break;
+      case 'u':
+	flags |= DP_F_UNSIGNED;
+	if (cflags == DP_C_SHORT)
+	  value = va_arg(args, unsigned short int);
+	else if (cflags == DP_C_LONG)
+	  value = va_arg(args, unsigned long int);
+	else
+	  value = va_arg(args, unsigned int);
+	fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
+	break;
+      case 'X':
+	flags |= DP_F_UP;
+      case 'x':
+	flags |= DP_F_UNSIGNED;
+	if (cflags == DP_C_SHORT)
+	  value = va_arg(args, unsigned short int);
+	else if (cflags == DP_C_LONG)
+	  value = va_arg(args, unsigned long int);
+	else
+	  value = va_arg(args, unsigned int);
+	fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags);
+	break;
+      case 'f':
+	if (cflags == DP_C_LDOUBLE)
+	  fvalue = va_arg(args, LDOUBLE);
+	else
+	  fvalue = va_arg(args, double);
+	/* um, floating point? */
+	fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags);
+	break;
+      case 'E':
+	flags |= DP_F_UP;
+      case 'e':
+	if (cflags == DP_C_LDOUBLE)
+	  fvalue = va_arg(args, LDOUBLE);
+	else
+	  fvalue = va_arg(args, double);
+	break;
+      case 'G':
+	flags |= DP_F_UP;
+      case 'g':
+	if (cflags == DP_C_LDOUBLE)
+	  fvalue = va_arg(args, LDOUBLE);
+	else
+	  fvalue = va_arg(args, double);
+	break;
+      case 'c':
+	dopr_outch(buffer, &currlen, maxlen, va_arg(args, int));
+	break;
+      case 's':
+	strvalue = va_arg(args, char *);
+	if (max < 0)
+	  max = maxlen;		/* ie, no max */
+	fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max);
+	break;
+      case 'p':
+	strvalue = va_arg(args, void *);
+	fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max,
+	       flags);
+	break;
+      case 'n':
+	if (cflags == DP_C_SHORT) {
+	  short int *num;
+	  num = va_arg(args, short int *);
+	  *num = currlen;
+	} else if (cflags == DP_C_LONG) {
+	  long int *num;
+	  num = va_arg(args, long int *);
+	  *num = currlen;
+	} else {
+	  int *num;
+	  num = va_arg(args, int *);
+	  *num = currlen;
+	}
+	break;
+      case '%':
+	dopr_outch(buffer, &currlen, maxlen, ch);
+	break;
+      case 'w':
+	/* not supported yet, treat as next char */
+	ch = *format++;
+	break;
+      default:
+	/* Unknown, skip */
+	break;
+      }
+      ch = *format++;
+      state = DP_S_DEFAULT;
+      flags = cflags = min = 0;
+      max = -1;
+      break;
+    case DP_S_DONE:
+      break;
+    default:
+      /* hmm? */
+      break;			/* some picky compilers need this */
+    }
+  }
+  if (currlen < maxlen - 1)
+    buffer[currlen] = '\0';
+  else
+    buffer[maxlen - 1] = '\0';
+}
+
+static void fmtstr(char *buffer, size_t * currlen, size_t maxlen,
+		   char *value, int flags, int min, int max)
+{
+  int padlen,
+      strln;			/* amount to pad */
+  int cnt = 0;
+
+  if (value == 0) {
+    value = "<NULL>";
+  }
+
+  for (strln = 0; value[strln]; ++strln);	/* strlen */
+  padlen = min - strln;
+  if (padlen < 0)
+    padlen = 0;
+  if (flags & DP_F_MINUS)
+    padlen = -padlen;		/* Left Justify */
+
+  while ((padlen > 0) && (cnt < max)) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    --padlen;
+    ++cnt;
+  }
+  while (*value && (cnt < max)) {
+    dopr_outch(buffer, currlen, maxlen, *value++);
+    ++cnt;
+  }
+  while ((padlen < 0) && (cnt < max)) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    ++padlen;
+    ++cnt;
+  }
+}
+
+/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
+
+static void fmtint(char *buffer, size_t * currlen, size_t maxlen,
+		   long value, int base, int min, int max, int flags)
+{
+  int signvalue = 0;
+  unsigned long uvalue;
+  char convert[20];
+  int place = 0;
+  int spadlen = 0;		/* amount to space pad */
+  int zpadlen = 0;		/* amount to zero pad */
+  int caps = 0;
+
+  if (max < 0)
+    max = 0;
+
+  uvalue = value;
+
+  if (!(flags & DP_F_UNSIGNED)) {
+    if (value < 0) {
+      signvalue = '-';
+      uvalue = -value;
+    } else if (flags & DP_F_PLUS)	/* Do a sign (+/i) */
+      signvalue = '+';
+    else if (flags & DP_F_SPACE)
+      signvalue = ' ';
+  }
+
+  if (flags & DP_F_UP)
+    caps = 1;			/* Should characters be upper case? */
+
+  do {
+    convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+	[uvalue % (unsigned) base];
+    uvalue = (uvalue / (unsigned) base);
+  }
+  while (uvalue && (place < 20));
+  if (place == 20)
+    place--;
+  convert[place] = 0;
+
+  zpadlen = max - place;
+  spadlen = min - MAX(max, place) - (signvalue ? 1 : 0);
+  if (zpadlen < 0)
+    zpadlen = 0;
+  if (spadlen < 0)
+    spadlen = 0;
+  if (flags & DP_F_ZERO) {
+    zpadlen = MAX(zpadlen, spadlen);
+    spadlen = 0;
+  }
+  if (flags & DP_F_MINUS)
+    spadlen = -spadlen;		/* Left Justifty */
+
+#ifdef DEBUG_SNPRINTF
+  dprint(1,
+	 (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
+	  zpadlen, spadlen, min, max, place));
+#endif
+
+  /* Spaces */
+  while (spadlen > 0) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    --spadlen;
+  }
+
+  /* Sign */
+  if (signvalue)
+    dopr_outch(buffer, currlen, maxlen, signvalue);
+
+  /* Zeros */
+  if (zpadlen > 0) {
+    while (zpadlen > 0) {
+      dopr_outch(buffer, currlen, maxlen, '0');
+      --zpadlen;
+    }
+  }
+
+  /* Digits */
+  while (place > 0)
+    dopr_outch(buffer, currlen, maxlen, convert[--place]);
+
+  /* Left Justified spaces */
+  while (spadlen < 0) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    ++spadlen;
+  }
+}
+
+static LDOUBLE abs_val(LDOUBLE value)
+{
+  LDOUBLE result = value;
+
+  if (value < 0)
+    result = -value;
+
+  return result;
+}
+
+static LDOUBLE pow10(int exp)
+{
+  LDOUBLE result = 1;
+
+  while (exp) {
+    result *= 10;
+    exp--;
+  }
+
+  return result;
+}
+
+static long round(LDOUBLE value)
+{
+  long intpart;
+
+  intpart = value;
+  value = value - intpart;
+  if (value >= 0.5)
+    intpart++;
+
+  return intpart;
+}
+
+static void fmtfp(char *buffer, size_t * currlen, size_t maxlen,
+		  LDOUBLE fvalue, int min, int max, int flags)
+{
+  int signvalue = 0;
+  LDOUBLE ufvalue;
+  char iconvert[20];
+  char fconvert[20];
+  int iplace = 0;
+  int fplace = 0;
+  int padlen = 0;		/* amount to pad */
+  int zpadlen = 0;
+  int caps = 0;
+  long intpart;
+  long fracpart;
+
+  /*
+   * AIX manpage says the default is 0, but Solaris says the default
+   * is 6, and sprintf on AIX defaults to 6
+   */
+  if (max < 0)
+    max = 6;
+
+  ufvalue = abs_val(fvalue);
+
+  if (fvalue < 0)
+    signvalue = '-';
+  else if (flags & DP_F_PLUS)	/* Do a sign (+/i) */
+    signvalue = '+';
+  else if (flags & DP_F_SPACE)
+    signvalue = ' ';
+
+#if 0
+  if (flags & DP_F_UP)
+    caps = 1;			/* Should characters be upper case? */
+#endif
+
+  intpart = ufvalue;
+
+  /*
+   * Sorry, we only support 9 digits past the decimal because of our
+   * conversion method
+   */
+  if (max > 9)
+    max = 9;
+
+  /* We "cheat" by converting the fractional part to integer by
+   * multiplying by a factor of 10
+   */
+  fracpart = round((pow10(max)) * (ufvalue - intpart));
+
+  if (fracpart >= pow10(max)) {
+    intpart++;
+    fracpart -= pow10(max);
+  }
+
+  /* Convert integer part */
+  do {
+    iconvert[iplace++] =
+	(caps ? "0123456789ABCDEF" : "0123456789abcdef")[intpart % 10];
+    intpart = (intpart / 10);
+  }
+  while (intpart && (iplace < 20));
+  if (iplace == 20)
+    iplace--;
+  iconvert[iplace] = 0;
+
+  /* Convert fractional part */
+  do {
+    fconvert[fplace++] =
+	(caps ? "0123456789ABCDEF" : "0123456789abcdef")[fracpart % 10];
+    fracpart = (fracpart / 10);
+  }
+  while (fracpart && (fplace < 20));
+  if (fplace == 20)
+    fplace--;
+  fconvert[fplace] = 0;
+
+  /* -1 for decimal point, another -1 if we are printing a sign */
+  padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
+  zpadlen = max - fplace;
+  if (zpadlen < 0)
+    zpadlen = 0;
+  if (padlen < 0)
+    padlen = 0;
+  if (flags & DP_F_MINUS)
+    padlen = -padlen;		/* Left Justifty */
+
+  if ((flags & DP_F_ZERO) && (padlen > 0)) {
+    if (signvalue) {
+      dopr_outch(buffer, currlen, maxlen, signvalue);
+      --padlen;
+      signvalue = 0;
+    }
+    while (padlen > 0) {
+      dopr_outch(buffer, currlen, maxlen, '0');
+      --padlen;
+    }
+  }
+  while (padlen > 0) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    --padlen;
+  }
+  if (signvalue)
+    dopr_outch(buffer, currlen, maxlen, signvalue);
+
+  while (iplace > 0)
+    dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);
+
+  /*
+   * Decimal point.  This should probably use locale to find the correct
+   * char to print out.
+   */
+  if (max > 0) {
+    dopr_outch(buffer, currlen, maxlen, '.');
+
+    while (fplace > 0)
+      dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);
+  }
+
+  while (zpadlen > 0) {
+    dopr_outch(buffer, currlen, maxlen, '0');
+    --zpadlen;
+  }
+
+  while (padlen < 0) {
+    dopr_outch(buffer, currlen, maxlen, ' ');
+    ++padlen;
+  }
+}
+
+static void dopr_outch(char *buffer, size_t * currlen, size_t maxlen,
+		       char c)
+{
+  if (*currlen < maxlen)
+    buffer[(*currlen)++] = c;
+}
+
+int egg_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
+{
+  str[0] = 0;
+  dopr(str, count, fmt, args);
+  return (strlen(str));
+}
+#endif				/* !HAVE_VSNPRINTF */
+
+#ifndef HAVE_SNPRINTF
+#  ifdef HAVE_STDARGS
+int egg_snprintf(char *str, size_t count, const char *fmt, ...)
+#  else
+int egg_snprintf(va_alist) va_dcl
+#  endif
+{
+#  ifndef HAVE_STDARGS
+  char *str;
+  size_t count;
+  char *fmt;
+#  endif
+  VA_LOCAL_DECL;
+
+  VA_START(fmt);
+  VA_SHIFT(str, char *);
+  VA_SHIFT(count, size_t);
+  VA_SHIFT(fmt, char *);
+  (void) egg_vsnprintf(str, count, fmt, ap);
+  VA_END;
+  return (strlen(str));
+}
+#endif				/* !HAVE_SNPRINTF */

+ 53 - 0
src/compat/snprintf.h

@@ -0,0 +1,53 @@
+/*
+ * snprintf.h
+ *   header file for snprintf.c
+ *
+ * $Id: snprintf.h,v 1.8 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_COMPAT_SNPRINTF_H_
+#define _EGG_COMPAT_SNPRINTF_H_
+
+#include "src/main.h"
+#include <stdio.h>
+
+/* Use the system libraries version of vsnprintf() if available. Otherwise
+ * use our own.
+ */
+#ifndef HAVE_VSNPRINTF
+int egg_vsnprintf(char *str, size_t count, const char *fmt, va_list ap);
+#else
+#  define egg_vsnprintf	vsnprintf
+#endif
+
+/* Use the system libraries version of snprintf() if available. Otherwise
+ * use our own.
+ */
+#ifndef HAVE_SNPRINTF
+#  ifdef __STDC__
+int egg_snprintf(char *str, size_t count, const char *fmt, ...);
+#  else
+int egg_snprintf();
+#  endif
+#else
+#  define egg_snprintf	snprintf
+#endif
+
+#endif	/* !_EGG_COMPAT_SNPRINTF_H_ */

+ 50 - 0
src/compat/strcasecmp.c

@@ -0,0 +1,50 @@
+/*
+ * strcasecmp.c -- provides strcasecmp() and strncasecmp if necessary.
+ *
+ * $Id: strcasecmp.c,v 1.3 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 "main.h"
+#include "memcpy.h"
+
+#ifndef HAVE_STRCASECMP
+int egg_strcasecmp(const char *s1, const char *s2)
+{
+  while ((*s1) && (*s2) && (toupper(*s1) == toupper(*s2))) {
+    s1++;
+    s2++;
+  }
+  return toupper(*s1) - toupper(*s2);
+}
+#endif /* !HAVE_STRCASECMP */
+
+#ifndef HAVE_STRNCASECMP
+int egg_strncasecmp(const char *s1, const char *s2, size_t n)
+{
+  if (!n)
+    return 0;
+  while (--n && (*s1) && (*s2) && (toupper(*s1) == toupper(*s2))) {
+    s1++;
+    s2++;
+  }
+  return toupper(*s1) - toupper(*s2);
+}
+#endif /* !HAVE_STRNCASECMP */

+ 46 - 0
src/compat/strcasecmp.h

@@ -0,0 +1,46 @@
+/*
+ * strcasecmp.h
+ *   prototypes for strcasecmp.c
+ *
+ * $Id: strcasecmp.h,v 1.4 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_COMPAT_STRCASECMP_H
+#define _EGG_COMPAT_STRCASECMP_H
+
+#include "src/main.h"
+#include <ctype.h>
+
+
+#ifndef HAVE_STRCASECMP
+/* Use our own implementation. */
+int egg_strcasecmp(const char *, const char *);
+#else
+#  define egg_strcasecmp	strcasecmp
+#endif
+
+#ifndef HAVE_STRNCASECMP
+/* Use our own implementation. */
+int egg_strncasecmp(const char *, const char *, size_t);
+#else
+#  define egg_strncasecmp	strncasecmp
+#endif
+
+#endif	/* !__EGG_COMPAT_STRCASECMP_H */

+ 35 - 0
src/compat/strftime.c

@@ -0,0 +1,35 @@
+/*
+ * strftime.c
+ *   Portable strftime implementation. Uses GNU's strftime().
+ *
+ * $Id: strftime.c,v 1.3 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ * Written by Fabian Knittel
+ *
+ * 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 "src/main.h"
+#include "strftime.h"
+
+#ifndef HAVE_STRFTIME
+#  undef emacs
+#  undef _LIBC
+#  define strftime	egg_strftime
+
+#  include "gnu_strftime.c"
+#endif	/* !HAVE_STRFTIME */

+ 42 - 0
src/compat/strftime.h

@@ -0,0 +1,42 @@
+/*
+ * strftime.h
+ *   header file for strftime.c
+ *
+ * $Id: strftime.h,v 1.3 2002/01/02 03:46:36 guppy Exp $
+ */
+/* 
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ * Written by Fabian Knittel
+ * 
+ * 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 _EGG_COMPAT_STRFTIME_H_
+#define _EGG_COMPAT_STRFTIME_H_
+
+#include "src/main.h"
+#include <time.h>
+
+/* Use the system libraries version of strftime() if available. Otherwise
+ * use our own.
+ */
+#ifndef HAVE_STRFTIME
+size_t egg_strftime(char *s, size_t maxsize, const char *format,
+		    const struct tm *tp);
+#else
+#  define egg_strftime	strftime
+#endif
+
+#endif	/* !_EGG_COMPAT_STRFTIME_H_ */

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 263 - 229
src/dcc.c


+ 161 - 126
src/dccutil.c

@@ -1,53 +1,52 @@
-/* 
+/*
  * dccutil.c -- handles:
  *   lots of little functions to send formatted text to
  *   varying types of connections
  *   '.who', '.whom', and '.dccstat' code
  *   memory management for dcc structures
  *   timeout checking for dcc connections
- * 
- * dprintf'ized, 28aug1995
- * 
- * $Id: dccutil.c,v 1.13 2000/01/17 16:14:45 per Exp $
+ *
+ * $Id: dccutil.c,v 1.39 2002/07/09 05:40:55 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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 "main.h"
 #include <sys/stat.h>
+#include "main.h"
 #include <errno.h>
 #include "chan.h"
 #include "modules.h"
 #include "tandem.h"
 
-extern struct dcc_t *dcc;
-extern int dcc_total, max_dcc, dcc_flood_thr, backgrd;
-extern char botnetnick[], spaces[], version[];
-extern time_t now;
+extern struct dcc_t	*dcc;
+extern int		 dcc_total, max_dcc, dcc_flood_thr, backgrd, MAXSOCKS;
+extern char		 botnetnick[], version[];
+extern time_t		 now;
+extern sock_list	*socklist;
+extern Tcl_Interp	*interp;
 
-char motdfile[121] = "motd";	/* file where the motd is stored */
-int connect_timeout = 15;	/* how long to wait before a telnet
-				 * connection times out */
-int reserved_port = 0;
+char	motdfile[121] = "text/motd";	/* File where the motd is stored */
+int	connect_timeout = 15;		/* How long to wait before a telnet
+					   connection times out */
 
-extern sock_list *socklist;
-extern int MAXSOCKS;
+int reserved_port_min = 0;
+int reserved_port_max = 0;
 
 void init_dcc_max()
 {
@@ -57,7 +56,6 @@ void init_dcc_max()
     max_dcc = 1;
   if (dcc)
     dcc = nrealloc(dcc, sizeof(struct dcc_t) * max_dcc);
-
   else
     dcc = nmalloc(sizeof(struct dcc_t) * max_dcc);
 
@@ -75,7 +73,6 @@ int expmem_dccutil()
 {
   int tot, i;
 
-  Context;
   tot = sizeof(struct dcc_t) * max_dcc + sizeof(sock_list) * MAXSOCKS;
 
   for (i = 0; i < dcc_total; i++) {
@@ -85,9 +82,8 @@ int expmem_dccutil()
   return tot;
 }
 
-static char SBUF[1024];
 
-/* replace \n with \r\n */
+/* Replace \n with \r\n */
 char *add_cr(char *buf)
 {
   static char WBUF[1024];
@@ -106,145 +102,151 @@ extern void (*qserver) (int, char *, int);
 
 void dprintf EGG_VARARGS_DEF(int, arg1)
 {
+  static char buf[1024];
   char *format;
   int idx, len;
-
   va_list va;
+
   idx = EGG_VARARGS_START(int, arg1, va);
   format = va_arg(va, char *);
-
-#ifdef HAVE_VSNPRINTF
-  if ((len = vsnprintf(SBUF, 1023, format, va)) < 0)
-    SBUF[len = 1023] = 0;
-#else
-  len = vsprintf(SBUF, format, va);
-#endif
+  egg_vsnprintf(buf, 1023, format, va);
   va_end(va);
+  /* We can not use the return value vsnprintf() to determine where
+   * to null terminate. The C99 standard specifies that vsnprintf()
+   * shall return the number of bytes that would be written if the
+   * buffer had been large enough, rather then -1.
+   */
+  /* We actually can, since if it's < 0 or >= sizeof(buf), we know it wrote
+   * sizeof(buf) bytes. But we're not doing that anyway.
+  */
+  buf[sizeof(buf)-1] = 0;
+  len = strlen(buf);
+
   if (idx < 0) {
-    tputs(-idx, SBUF, len);
+    tputs(-idx, buf, len);
   } else if (idx > 0x7FF0) {
     switch (idx) {
     case DP_LOG:
-      putlog(LOG_MISC, "*", "%s", SBUF);
+      putlog(LOG_MISC, "*", "%s", buf);
       break;
     case DP_STDOUT:
-      tputs(STDOUT, SBUF, len);
+      tputs(STDOUT, buf, len);
       break;
     case DP_STDERR:
-      tputs(STDERR, SBUF, len);
+      tputs(STDERR, buf, len);
       break;
     case DP_SERVER:
     case DP_HELP:
     case DP_MODE:
-      qserver(idx, SBUF, len);
+    case DP_MODE_NEXT:
+    case DP_SERVER_NEXT:
+    case DP_HELP_NEXT:
+      qserver(idx, buf, len);
       break;
     }
     return;
   } else {
-    if (len > 500) {		/* truncate to fit */
-      SBUF[500] = 0;
-      strcat(SBUF, "\n");
+    if (len > 500) {		/* Truncate to fit */
+      buf[500] = 0;
+      strcat(buf, "\n");
       len = 501;
     }
     if (dcc[idx].type && ((long) (dcc[idx].type->output) == 1)) {
-      char *p = add_cr(SBUF);
+      char *p = add_cr(buf);
 
       tputs(dcc[idx].sock, p, strlen(p));
     } else if (dcc[idx].type && dcc[idx].type->output) {
-      dcc[idx].type->output(idx, SBUF, dcc[idx].u.other);
+      dcc[idx].type->output(idx, buf, dcc[idx].u.other);
     } else
-      tputs(dcc[idx].sock, SBUF, len);
+      tputs(dcc[idx].sock, buf, len);
   }
 }
 
 void chatout EGG_VARARGS_DEF(char *, arg1)
 {
-  int i;
+  int i, len;
   char *format;
   char s[601];
-
   va_list va;
+
   format = EGG_VARARGS_START(char *, arg1, va);
+  egg_vsnprintf(s, 511, format, va);
+  va_end(va);
+  len = strlen(s);
+  if (len > 511)
+    len = 511;
+  s[len + 1] = 0;
 
-#ifdef HAVE_VSNPRINTF
-  if (vsnprintf(s, 511, format, va) < 0)
-    s[511] = 0;
-#else
-  vsprintf(s, format, va);
-#endif
   for (i = 0; i < dcc_total; i++)
     if (dcc[i].type == &DCC_CHAT)
       if (dcc[i].u.chat->channel >= 0)
-	dprintf(i, "%s", s);
-  va_end(va);
+        dprintf(i, "%s", s);
+
 }
 
-/* print to all on this channel but one */
+/* Print to all on this channel but one.
+ */
 void chanout_but EGG_VARARGS_DEF(int, arg1)
 {
-  int i, x, chan;
+  int i, x, chan, len;
   char *format;
   char s[601];
-
   va_list va;
+
   x = EGG_VARARGS_START(int, arg1, va);
   chan = va_arg(va, int);
   format = va_arg(va, char *);
+  egg_vsnprintf(s, 511, format, va);
+  va_end(va);
+  len = strlen(s);
+  if (len > 511)
+    len = 511;
+  s[len + 1] = 0;
 
-#ifdef HAVE_VSNPRINTF
-  if (vsnprintf(s, 511, format, va) < 0)
-    s[511] = 0;
-#else
-  vsprintf(s, format, va);
-#endif
   for (i = 0; i < dcc_total; i++)
     if ((dcc[i].type == &DCC_CHAT) && (i != x))
       if (dcc[i].u.chat->channel == chan)
-	dprintf(i, "%s", s);
-  va_end(va);
+        dprintf(i, "%s", s);
+
 }
 
 void dcc_chatter(int idx)
 {
   int i, j;
-  struct flag_record fr =
-  {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
+  struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
 
   get_user_flagrec(dcc[idx].user, &fr, NULL);
-  dprintf(idx, "Connected to %s, running %s\n", botnetnick, version);
   show_motd(idx);
-  dprintf(idx, "Commands start with '.' (like '.quit' or '.help')\n");
-  dprintf(idx, "Everything else goes out to the party line.\n\n");
   i = dcc[idx].u.chat->channel;
   dcc[idx].u.chat->channel = 234567;
   j = dcc[idx].sock;
   strcpy(dcc[idx].u.chat->con_chan, "***");
   check_tcl_chon(dcc[idx].nick, dcc[idx].sock);
-  /* still there? */
+  /* Still there? */
   if ((idx >= dcc_total) || (dcc[idx].sock != j))
-    return;			/* nope */
-  /* tcl script may have taken control */
+    return;			/* Nope */
+  /* Tcl script may have taken control */
   if (dcc[idx].type == &DCC_CHAT) {
     if (!strcmp(dcc[idx].u.chat->con_chan, "***"))
       strcpy(dcc[idx].u.chat->con_chan, "*");
     if (dcc[idx].u.chat->channel == 234567) {
-      /* if the chat channel has already been altered it's *highly*
+      /* If the chat channel has already been altered it's *highly*
        * probably join/part messages have been broadcast everywhere,
-       * so dont bother sending them */
+       * so dont bother sending them
+       */
       if (i == -2)
 	i = 0;
       dcc[idx].u.chat->channel = i;
       if (dcc[idx].u.chat->channel >= 0) {
-	Context;
-	if (dcc[idx].u.chat->channel < 100000) {
+	if (dcc[idx].u.chat->channel < GLOBAL_CHANS) {
 	  botnet_send_join_idx(idx, -1);
 	}
       }
       check_tcl_chjn(botnetnick, dcc[idx].nick, dcc[idx].u.chat->channel,
 		     geticon(idx), dcc[idx].sock, dcc[idx].host);
     }
-    /* but *do* bother with sending it locally */
-    if (dcc[idx].u.chat->channel == 0) {
+    /* But *do* bother with sending it locally */
+    if (!dcc[idx].u.chat->channel) {
       chanout_but(-1, 0, "*** %s joined the party line.\n", dcc[idx].nick);
     } else if (dcc[idx].u.chat->channel > 0) {
       chanout_but(-1, dcc[idx].u.chat->channel,
@@ -258,11 +260,14 @@ void dcc_chatter(int idx)
  */
 void lostdcc(int n)
 {
+  /* Make sure it's a valid dcc index. */
+  if (n < 0 || n >= max_dcc) return;
+
   if (dcc[n].type && dcc[n].type->kill)
     dcc[n].type->kill(n, dcc[n].u.other);
   else if (dcc[n].u.other)
     nfree(dcc[n].u.other);
-  bzero(&dcc[n], sizeof(struct dcc_t));
+  egg_bzero(&dcc[n], sizeof(struct dcc_t));
 
   dcc[n].sock = (-1);
   dcc[n].type = &DCC_LOST;
@@ -271,6 +276,9 @@ void lostdcc(int n)
 /* Remove entry from dcc list. Think twice before using this function,
  * because it invalidates any variables that point to a specific dcc
  * entry!
+ *
+ * Note: The entry will be deconstructed if it was not deconstructed
+ *       already. This case should normally not occur.
  */
 void removedcc(int n)
 {
@@ -280,10 +288,9 @@ void removedcc(int n)
     nfree(dcc[n].u.other);
   dcc_total--;
   if (n < dcc_total)
-    my_memcpy((char *) &dcc[n], (char *) &dcc[dcc_total],
-	      sizeof(struct dcc_t));
+    egg_memcpy(&dcc[n], &dcc[dcc_total], sizeof(struct dcc_t));
   else
-    bzero(&dcc[n], sizeof(struct dcc_t)); /* drummer */
+    egg_bzero(&dcc[n], sizeof(struct dcc_t)); /* drummer */
 }
 
 /* Clean up sockets that were just left for dead.
@@ -292,7 +299,6 @@ void dcc_remove_lost(void)
 {
   int i;
 
-  Context;
   for (i = 0; i < dcc_total; i++) {
     if (dcc[i].type == &DCC_LOST) {
       dcc[i].type = NULL;
@@ -303,21 +309,33 @@ void dcc_remove_lost(void)
   }
 }
 
-/* show list of current dcc's to a dcc-chatter */
-/* positive value: idx given -- negative value: sock given */
+/* Show list of current dcc's to a dcc-chatter
+ * positive value: idx given -- negative value: sock given
+ */
 void tell_dcc(int zidx)
 {
-  int i, j, k;
+  int i, j;
   char other[160];
+  char format[81];
+  int nicklen;
 
-  Context;
-  spaces[HANDLEN - 9] = 0;
-  dprintf(zidx, "SOCK ADDR     PORT  NICK     %s HOST              TYPE\n"
-	  ,spaces);
-  dprintf(zidx, "---- -------- ----- ---------%s ----------------- ----\n"
-	  ,spaces);
-  spaces[HANDLEN - 9] = ' ';
-  /* show server */
+  /* calculate max nicklen */
+  nicklen = 0;
+  for (i = 0; i < dcc_total; i++) {
+      if(strlen(dcc[i].nick) > nicklen)
+          nicklen = strlen(dcc[i].nick);
+  }
+  if(nicklen < 9) nicklen = 9;
+  
+  snprintf(format, sizeof format, "%%-4s %%-8s %%-5s %%-%us %%-17s %%s\n", 
+                          nicklen);
+  dprintf(zidx, format, "SOCK", "ADDR",     "PORT",  "NICK", "HOST", "TYPE");
+  dprintf(zidx, format, "----", "--------", "-----", "---------", 
+                        "-----------------", "----");
+
+  snprintf(format, sizeof format, "%%-4d %%08X %%5d %%-%us %%-17s %%s\n", 
+                          nicklen);
+  /* Show server */
   for (i = 0; i < dcc_total; i++) {
     j = strlen(dcc[i].host);
     if (j > 17)
@@ -330,18 +348,15 @@ void tell_dcc(int zidx)
       sprintf(other, "?:%lX  !! ERROR !!", (long) dcc[i].type);
       break;
     }
-    k = HANDLEN - strlen(dcc[i].nick);
-    spaces[k] = 0;
-    dprintf(zidx, "%-4d %08X %5d %s%s %-17s %s\n", dcc[i].sock, dcc[i].addr,
-	    dcc[i].port, dcc[i].nick, spaces, dcc[i].host + j, other);
-    spaces[k] = ' ';
+    dprintf(zidx, format, dcc[i].sock, dcc[i].addr, dcc[i].port, dcc[i].nick, 
+			  dcc[i].host + j, other);
   }
 }
 
-/* mark someone on dcc chat as no longer away */
+/* Mark someone on dcc chat as no longer away
+ */
 void not_away(int idx)
 {
-  Context;
   if (dcc[idx].u.chat->away == NULL) {
     dprintf(idx, "You weren't away!\n");
     return;
@@ -349,8 +364,7 @@ void not_away(int idx)
   if (dcc[idx].u.chat->channel >= 0) {
     chanout_but(-1, dcc[idx].u.chat->channel,
 		"*** %s is no longer away.\n", dcc[idx].nick);
-    Context;
-    if (dcc[idx].u.chat->channel < 100000) {
+    if (dcc[idx].u.chat->channel < GLOBAL_CHANS) {
       botnet_send_away(-1, botnetnick, dcc[idx].sock, NULL, idx);
     }
   }
@@ -377,8 +391,7 @@ void set_away(int idx, char *s)
   if (dcc[idx].u.chat->channel >= 0) {
     chanout_but(-1, dcc[idx].u.chat->channel,
 		"*** %s is now away: %s\n", dcc[idx].nick, s);
-    Context;
-    if (dcc[idx].u.chat->channel < 100000) {
+    if (dcc[idx].u.chat->channel < GLOBAL_CHANS) {
       botnet_send_away(-1, botnetnick, dcc[idx].sock, s, idx);
     }
   }
@@ -386,24 +399,26 @@ void set_away(int idx, char *s)
   check_tcl_away(botnetnick, dcc[idx].sock, s);
 }
 
-/* this helps the memory debugging */
+/* This helps the memory debugging
+ */
 void *_get_data_ptr(int size, char *file, int line)
 {
   char *p;
-
 #ifdef DEBUG_MEM
   char x[1024];
 
-  simple_sprintf(x, "dccutil.c:%s", file);
+  p = strrchr(file, '/');
+  egg_snprintf(x, sizeof x, "dccutil.c:%s", p ? p + 1 : file);
   p = n_malloc(size, x, line);
 #else
   p = nmalloc(size);
 #endif
-  bzero(p, size);
+  egg_bzero(p, size);
   return p;
 }
 
-/* make a password, 10-15 random letters and digits */
+/* Make a password, 10-15 random letters and digits
+ */
 void makepass(char *s)
 {
   int i;
@@ -443,22 +458,40 @@ int new_dcc(struct dcc_table *type, int xtra_size)
   if (dcc_total == max_dcc)
     return -1;
   dcc_total++;
-  bzero((char *) &dcc[i], sizeof(struct dcc_t));
+  egg_bzero((char *) &dcc[i], sizeof(struct dcc_t));
 
   dcc[i].type = type;
   if (xtra_size) {
     dcc[i].u.other = nmalloc(xtra_size);
-    bzero(dcc[i].u.other, xtra_size);
+    egg_bzero(dcc[i].u.other, xtra_size);
   }
   return i;
+}
+
+/* Changes the given dcc entry to another type.
+ */
+void changeover_dcc(int i, struct dcc_table *type, int xtra_size)
+{
+  /* Free old structure. */
+  if (dcc[i].type && dcc[i].type->kill)
+    dcc[i].type->kill(i, dcc[i].u.other);
+  else if (dcc[i].u.other) {
+    nfree(dcc[i].u.other);
+    dcc[i].u.other = NULL;
+  }
 
+  dcc[i].type = type;
+  if (xtra_size) {
+    dcc[i].u.other = nmalloc(xtra_size);
+    egg_bzero(dcc[i].u.other, xtra_size);
+  }
 }
 
 int detect_dcc_flood(time_t * timer, struct chat_info *chat, int idx)
 {
   time_t t;
 
-  if (dcc_flood_thr == 0)
+  if (!dcc_flood_thr)
     return 0;
   t = now;
   if (*timer != t) {
@@ -469,14 +502,14 @@ int detect_dcc_flood(time_t * timer, struct chat_info *chat, int idx)
     if (chat->msgs_per_sec > dcc_flood_thr) {
       /* FLOOD */
       dprintf(idx, "*** FLOOD: %s.\n", IRC_GOODBYE);
-      /* evil assumption here that flags&DCT_CHAT implies chat type */
+      /* Evil assumption here that flags&DCT_CHAT implies chat type */
       if ((dcc[idx].type->flags & DCT_CHAT) && chat &&
 	  (chat->channel >= 0)) {
 	char x[1024];
 
-	simple_sprintf(x, DCC_FLOODBOOT, dcc[idx].nick);
+	egg_snprintf(x, sizeof x, DCC_FLOODBOOT, dcc[idx].nick);
 	chanout_but(idx, chat->channel, "*** %s", x);
-	if (chat->channel < 100000)
+	if (chat->channel < GLOBAL_CHANS)
 	  botnet_send_part_idx(idx, x);
       }
       check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
@@ -493,31 +526,33 @@ int detect_dcc_flood(time_t * timer, struct chat_info *chat, int idx)
   return 0;
 }
 
-/* handle someone being booted from dcc chat */
+/* Handle someone being booted from dcc chat.
+ */
 void do_boot(int idx, char *by, char *reason)
 {
   int files = (dcc[idx].type != &DCC_CHAT);
 
   dprintf(idx, DCC_BOOTED1);
-  dprintf(idx, DCC_BOOTED2, DCC_BOOTED2_ARGS);
-  /* if it's a partyliner (chatterer :) */
-  /* horrible assumption that DCT_CHAT using structure uses same format
+  dprintf(idx, DCC_BOOTED2, files ? "file section" : "bot",
+          by, reason[0] ? ": " : ".", reason);
+  /* If it's a partyliner (chatterer :) */
+  /* Horrible assumption that DCT_CHAT using structure uses same format
    * as DCC_CHAT */
   if ((dcc[idx].type->flags & DCT_CHAT) &&
       (dcc[idx].u.chat->channel >= 0)) {
     char x[1024];
 
-    simple_sprintf(x, "%s booted %s from the party line%s%s",
-		   by, dcc[idx].nick, reason[0] ? ": " : "", reason);
+    egg_snprintf(x, sizeof x, DCC_BOOTED3, by, dcc[idx].nick,
+		 reason[0] ? ": " : "", reason);
     chanout_but(idx, dcc[idx].u.chat->channel, "*** %s.\n", x);
-    if (dcc[idx].u.chat->channel < 100000)
+    if (dcc[idx].u.chat->channel < GLOBAL_CHANS)
       botnet_send_part_idx(idx, x);
   }
   check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
   if ((dcc[idx].sock != STDOUT) || backgrd) {
     killsock(dcc[idx].sock);
     lostdcc(idx);
-    /* entry must remain in the table so it can be logged by the caller */
+    /* Entry must remain in the table so it can be logged by the caller */
   } else {
     dprintf(DP_STDOUT, "\n### SIMULATION RESET\n\n");
     dcc_chatter(idx);

+ 539 - 0
src/dns.c

@@ -0,0 +1,539 @@
+/*
+ * dns.c -- handles:
+ *   DNS resolve calls and events
+ *   provides the code used by the bot if the DNS module is not loaded
+ *   DNS Tcl commands
+ *
+ * $Id: dns.c,v 1.24 2002/01/02 03:46:35 guppy Exp $
+ */
+/*
+ * Written by Fabian Knittel <fknittel@gmx.de>
+ *
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 "main.h"
+#include <netdb.h>
+#include <setjmp.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "dns.h"
+
+extern struct dcc_t	*dcc;
+extern int		 dcc_total;
+extern int		 resolve_timeout;
+extern time_t		 now;
+extern jmp_buf		 alarmret;
+extern Tcl_Interp	*interp;
+
+devent_t	*dns_events = NULL;
+
+
+/*
+ *   DCC functions
+ */
+
+void dcc_dnswait(int idx, char *buf, int len)
+{
+  /* Ignore anything now. */
+}
+
+void eof_dcc_dnswait(int idx)
+{
+  putlog(LOG_MISC, "*", "Lost connection while resolving hostname [%s/%d]",
+	 iptostr(htonl(dcc[idx].addr)), dcc[idx].port);
+  killsock(dcc[idx].sock);
+  lostdcc(idx);
+}
+
+static void display_dcc_dnswait(int idx, char *buf)
+{
+  sprintf(buf, "dns   waited %lus", now - dcc[idx].timeval);
+}
+
+static int expmem_dcc_dnswait(void *x)
+{
+  register struct dns_info *p = (struct dns_info *) x;
+  int size = 0;
+
+  if (p) {
+    size = sizeof(struct dns_info);
+    if (p->host)
+      size += strlen(p->host) + 1;
+    if (p->cbuf)
+      size += strlen(p->cbuf) + 1;
+  }
+  return size;
+}
+
+static void kill_dcc_dnswait(int idx, void *x)
+{
+  register struct dns_info *p = (struct dns_info *) x;
+
+  if (p) {
+    if (p->host)
+      nfree(p->host);
+    if (p->cbuf)
+      nfree(p->cbuf);
+    nfree(p);
+  }
+}
+
+struct dcc_table DCC_DNSWAIT =
+{
+  "DNSWAIT",
+  DCT_VALIDIDX,
+  eof_dcc_dnswait,
+  dcc_dnswait,
+  0,
+  0,
+  display_dcc_dnswait,
+  expmem_dcc_dnswait,
+  kill_dcc_dnswait,
+  0
+};
+
+
+/*
+ *   DCC events
+ */
+
+/* Walk through every dcc entry and look for waiting DNS requests
+ * of RES_HOSTBYIP for our IP address.
+ */
+static void dns_dcchostbyip(IP ip, char *hostn, int ok, void *other)
+{
+  int idx;
+
+  for (idx = 0; idx < dcc_total; idx++) {
+    if ((dcc[idx].type == &DCC_DNSWAIT) &&
+        (dcc[idx].u.dns->dns_type == RES_HOSTBYIP) &&
+        (dcc[idx].u.dns->ip == ip)) {
+      if (dcc[idx].u.dns->host)
+        nfree(dcc[idx].u.dns->host);
+      dcc[idx].u.dns->host = get_data_ptr(strlen(hostn) + 1);
+      strcpy(dcc[idx].u.dns->host, hostn);
+      if (ok)
+        dcc[idx].u.dns->dns_success(idx);
+      else
+        dcc[idx].u.dns->dns_failure(idx);
+    }
+  }
+}
+
+/* Walk through every dcc entry and look for waiting DNS requests
+ * of RES_IPBYHOST for our hostname.
+ */
+static void dns_dccipbyhost(IP ip, char *hostn, int ok, void *other)
+{
+  int idx;
+
+  for (idx = 0; idx < dcc_total; idx++) {
+    if ((dcc[idx].type == &DCC_DNSWAIT) &&
+        (dcc[idx].u.dns->dns_type == RES_IPBYHOST) &&
+        !egg_strcasecmp(dcc[idx].u.dns->host, hostn)) {
+      dcc[idx].u.dns->ip = ip;
+      if (ok)
+        dcc[idx].u.dns->dns_success(idx);
+      else
+        dcc[idx].u.dns->dns_failure(idx);
+    }
+  }
+}
+
+static int dns_dccexpmem(void *other)
+{
+  return 0;
+}
+
+devent_type DNS_DCCEVENT_HOSTBYIP = {
+  "DCCEVENT_HOSTBYIP",
+  dns_dccexpmem,
+  dns_dcchostbyip
+};
+
+devent_type DNS_DCCEVENT_IPBYHOST = {
+  "DCCEVENT_IPBYHOST",
+  dns_dccexpmem,
+  dns_dccipbyhost
+};
+
+void dcc_dnsipbyhost(char *hostn)
+{
+  devent_t *de;
+
+  for (de = dns_events; de; de = de->next) {
+    if (de->type && (de->type == &DNS_DCCEVENT_IPBYHOST) &&
+	(de->lookup == RES_IPBYHOST)) {
+      if (de->res_data.hostname &&
+	  !egg_strcasecmp(de->res_data.hostname, hostn))
+	/* No need to add anymore. */
+	return;
+    }
+  }
+
+  de = nmalloc(sizeof(devent_t));
+  egg_bzero(de, sizeof(devent_t));
+
+  /* Link into list. */
+  de->next = dns_events;
+  dns_events = de;
+
+  de->type = &DNS_DCCEVENT_IPBYHOST;
+  de->lookup = RES_IPBYHOST;
+  de->res_data.hostname = nmalloc(strlen(hostn) + 1);
+  strcpy(de->res_data.hostname, hostn);
+
+  /* Send request. */
+  dns_ipbyhost(hostn);
+}
+
+void dcc_dnshostbyip(IP ip)
+{
+  devent_t *de;
+
+  for (de = dns_events; de; de = de->next) {
+    if (de->type && (de->type == &DNS_DCCEVENT_HOSTBYIP) &&
+	(de->lookup == RES_HOSTBYIP)) {
+      if (de->res_data.ip_addr == ip)
+	/* No need to add anymore. */
+	return;
+    }
+  }
+
+  de = nmalloc(sizeof(devent_t));
+  egg_bzero(de, sizeof(devent_t));
+
+  /* Link into list. */
+  de->next = dns_events;
+  dns_events = de;
+
+  de->type = &DNS_DCCEVENT_HOSTBYIP;
+  de->lookup = RES_HOSTBYIP;
+  de->res_data.ip_addr = ip;
+
+  /* Send request. */
+  dns_hostbyip(ip);
+}
+
+
+/*
+ *   Tcl events
+ */
+
+static void dns_tcl_iporhostres(IP ip, char *hostn, int ok, void *other)
+{
+  devent_tclinfo_t *tclinfo = (devent_tclinfo_t *) other;
+
+  if (Tcl_VarEval(interp, tclinfo->proc, " ", iptostr(htonl(ip)), " ",
+		  hostn, ok ? " 1" : " 0", tclinfo->paras, NULL) == TCL_ERROR)
+    putlog(LOG_MISC, "*", DCC_TCLERROR, tclinfo->proc, interp->result);
+
+  /* Free the memory. It will be unused after this event call. */
+  nfree(tclinfo->proc);
+  if (tclinfo->paras)
+    nfree(tclinfo->paras);
+  nfree(tclinfo);
+}
+
+static int dns_tclexpmem(void *other)
+{
+  devent_tclinfo_t *tclinfo = (devent_tclinfo_t *) other;
+  int l = 0;
+
+  if (tclinfo) {
+    l = sizeof(devent_tclinfo_t);
+    if (tclinfo->proc)
+      l += strlen(tclinfo->proc) + 1;
+    if (tclinfo->paras)
+      l += strlen(tclinfo->paras) + 1;
+  }
+  return l;
+}
+
+devent_type DNS_TCLEVENT_HOSTBYIP = {
+  "TCLEVENT_HOSTBYIP",
+  dns_tclexpmem,
+  dns_tcl_iporhostres
+};
+
+devent_type DNS_TCLEVENT_IPBYHOST = {
+  "TCLEVENT_IPBYHOST",
+  dns_tclexpmem,
+  dns_tcl_iporhostres
+};
+
+static void tcl_dnsipbyhost(char *hostn, char *proc, char *paras)
+{
+  devent_t *de;
+  devent_tclinfo_t *tclinfo;
+
+  de = nmalloc(sizeof(devent_t));
+  egg_bzero(de, sizeof(devent_t));
+
+  /* Link into list. */
+  de->next = dns_events;
+  dns_events = de;
+
+  de->type = &DNS_TCLEVENT_IPBYHOST;
+  de->lookup = RES_IPBYHOST;
+  de->res_data.hostname = nmalloc(strlen(hostn) + 1);
+  strcpy(de->res_data.hostname, hostn);
+
+  /* Store additional data. */
+  tclinfo = nmalloc(sizeof(devent_tclinfo_t));
+  tclinfo->proc = nmalloc(strlen(proc) + 1);
+  strcpy(tclinfo->proc, proc);
+  if (paras) {
+    tclinfo->paras = nmalloc(strlen(paras) + 1);
+    strcpy(tclinfo->paras, paras);
+  } else
+    tclinfo->paras = NULL;
+  de->other = tclinfo;
+
+  /* Send request. */
+  dns_ipbyhost(hostn);
+}
+
+static void tcl_dnshostbyip(IP ip, char *proc, char *paras)
+{
+  devent_t *de;
+  devent_tclinfo_t *tclinfo;
+
+  de = nmalloc(sizeof(devent_t));
+  egg_bzero(de, sizeof(devent_t));
+
+  /* Link into list. */
+  de->next = dns_events;
+  dns_events = de;
+
+  de->type = &DNS_TCLEVENT_HOSTBYIP;
+  de->lookup = RES_HOSTBYIP;
+  de->res_data.ip_addr = ip;
+
+  /* Store additional data. */
+  tclinfo = nmalloc(sizeof(devent_tclinfo_t));
+  tclinfo->proc = nmalloc(strlen(proc) + 1);
+  strcpy(tclinfo->proc, proc);
+  if (paras) {
+    tclinfo->paras = nmalloc(strlen(paras) + 1);
+    strcpy(tclinfo->paras, paras);
+  } else
+    tclinfo->paras = NULL;
+  de->other = tclinfo;
+
+  /* Send request. */
+  dns_hostbyip(ip);
+}
+
+
+/*
+ *    Event functions
+ */
+
+inline static int dnsevent_expmem(void)
+{
+  devent_t *de;
+  int tot = 0;
+
+  for (de = dns_events; de; de = de->next) {
+    tot += sizeof(devent_t);
+    if ((de->lookup == RES_IPBYHOST) && de->res_data.hostname)
+      tot += strlen(de->res_data.hostname) + 1;
+    if (de->type && de->type->expmem)
+      tot += de->type->expmem(de->other);
+  }
+  return tot;
+}
+
+void call_hostbyip(IP ip, char *hostn, int ok)
+{
+  devent_t *de = dns_events, *ode = NULL, *nde = NULL;
+
+  while (de) {
+    nde = de->next;
+    if ((de->lookup == RES_HOSTBYIP) &&
+	(!de->res_data.ip_addr || (de->res_data.ip_addr == ip))) {
+      /* Remove the event from the list here, to avoid conflicts if one of
+       * the event handlers re-adds another event. */
+      if (ode)
+	ode->next = de->next;
+      else
+	dns_events = de->next;
+
+      if (de->type && de->type->event)
+	de->type->event(ip, hostn, ok, de->other);
+      else
+	putlog(LOG_MISC, "*", "(!) Unknown DNS event type found: %s",
+	       (de->type && de->type->name) ? de->type->name : "<empty>");
+      nfree(de);
+      de = ode;
+    }
+    ode = de;
+    de = nde;
+  }
+}
+
+void call_ipbyhost(char *hostn, IP ip, int ok)
+{
+  devent_t *de = dns_events, *ode = NULL, *nde = NULL;
+
+  while (de) {
+    nde = de->next;
+    if ((de->lookup == RES_IPBYHOST) &&
+	(!de->res_data.hostname ||
+	 !egg_strcasecmp(de->res_data.hostname, hostn))) {
+      /* Remove the event from the list here, to avoid conflicts if one of
+       * the event handlers re-adds another event. */
+      if (ode)
+	ode->next = de->next;
+      else
+	dns_events = de->next;
+
+      if (de->type && de->type->event)
+	de->type->event(ip, hostn, ok, de->other);
+      else
+	putlog(LOG_MISC, "*", "(!) Unknown DNS event type found: %s",
+	       (de->type && de->type->name) ? de->type->name : "<empty>");
+
+      if (de->res_data.hostname)
+	nfree(de->res_data.hostname);
+      nfree(de);
+      de = ode;
+    }
+    ode = de;
+    de = nde;
+  }
+}
+
+
+/*
+ *    Async DNS emulation functions
+ */
+
+void block_dns_hostbyip(IP ip)
+{
+  struct hostent *hp;
+  unsigned long addr = htonl(ip);
+  static char s[UHOSTLEN];
+
+  if (!setjmp(alarmret)) {
+    alarm(resolve_timeout);
+    hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
+    alarm(0);
+    if (hp) {
+      strncpyz(s, hp->h_name, sizeof s);
+    } else
+      strcpy(s, iptostr(addr));
+  } else {
+    hp = NULL;
+    strcpy(s, iptostr(addr));
+  }
+  /* Call hooks. */
+  call_hostbyip(ip, s, hp ? 1 : 0);
+}
+
+void block_dns_ipbyhost(char *host)
+{
+  struct in_addr inaddr;
+
+  /* Check if someone passed us an IP address as hostname
+   * and return it straight away */
+  if (egg_inet_aton(host, &inaddr)) {
+    call_ipbyhost(host, ntohl(inaddr.s_addr), 1);
+    return;
+  }
+  if (!setjmp(alarmret)) {
+    struct hostent *hp;
+    struct in_addr *in;
+    IP ip = 0;
+
+    alarm(resolve_timeout);
+    hp = gethostbyname(host);
+    alarm(0);
+
+    if (hp) {
+      in = (struct in_addr *) (hp->h_addr_list[0]);
+      ip = (IP) (in->s_addr);
+      call_ipbyhost(host, ntohl(ip), 1);
+      return;
+    }
+    /* Fall through. */
+  }
+  call_ipbyhost(host, 0, 0);
+}
+
+
+/*
+ *   Misc functions
+ */
+
+int expmem_dns(void)
+{
+  return dnsevent_expmem();
+}
+
+
+/*
+ *   Tcl functions
+ */
+
+/* dnslookup <ip-address> <proc> */
+static int tcl_dnslookup STDVAR
+{
+  struct in_addr inaddr;
+  char *paras = NULL;
+
+  /* This function should be using BADARGS, FIXME -poptix */
+  if (argc < 3) {
+    Tcl_AppendResult(irp, "wrong # args: should be \"", argv[0],
+		     " ip-address/hostname proc ?args...?\"", NULL);
+    return TCL_ERROR;
+  }
+
+  if (argc > 3) {
+    int l = 0, p;
+
+    /* Create a string with a leading space out of all provided
+     * additional parameters.
+     */
+    paras = nmalloc(1);
+    paras[0] = 0;
+    for (p = 3; p < argc; p++) {
+      l += strlen(argv[p]) + 1;
+      paras = nrealloc(paras, l + 1);
+      strcat(paras, " ");
+      strcat(paras, argv[p]);
+    }
+  }
+
+  if (egg_inet_aton(argv[1], &inaddr))
+    tcl_dnshostbyip(ntohl(inaddr.s_addr), argv[2], paras);
+  else
+    tcl_dnsipbyhost(argv[1], argv[2], paras);
+  if (paras)
+    nfree(paras);
+  return TCL_OK;
+}
+
+tcl_cmds tcldns_cmds[] =
+{
+  {"dnslookup",	tcl_dnslookup},
+  {NULL,	NULL}
+};

+ 52 - 0
src/dns.h

@@ -0,0 +1,52 @@
+/*
+ * dns.h
+ *   stuff used by dns.c
+ *
+ * $Id: dns.h,v 1.7 2002/01/02 03:46:35 guppy Exp $
+ */
+/*
+ * Written by Fabian Knittel <fknittel@gmx.de>
+ *
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_DNS_H
+#define _EGG_DNS_H
+
+typedef struct {
+  char *name;
+  int  (*expmem)(void *);
+  void (*event)(IP, char *, int, void *);
+} devent_type;
+
+typedef struct {
+  char *proc;			/* Tcl proc			  */
+  char *paras;			/* Additional parameters	  */
+} devent_tclinfo_t;
+
+typedef struct devent_str {
+  struct devent_str *next;	/* Pointer to next dns_event	  */
+  devent_type	*type;
+  u_8bit_t	lookup;		/* RES_IPBYHOST or RES_HOSTBYIP	  */
+  union {
+    IP		ip_addr;	/* IP address			  */
+    char	*hostname; 	/* Hostname			  */
+  } res_data;
+  void		*other;		/* Data specific to the event type */
+} devent_t;
+
+#endif	/* _EGG_DNS_H */

+ 374 - 244
src/eggdrop.h

@@ -1,25 +1,25 @@
-/* 
+/*
  * eggdrop.h
  *   Eggdrop compile-time settings
- * 
+ *
  *   IF YOU ALTER THIS FILE, YOU NEED TO RECOMPILE THE BOT.
- * 
- * $Id: eggdrop.h,v 1.18 2000/01/08 21:23:14 per Exp $
+ *
+ * $Id: eggdrop.h,v 1.38 2002/01/02 03:46:35 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -28,189 +28,212 @@
 #ifndef _EGG_EGGDROP_H
 #define _EGG_EGGDROP_H
 
-/* 
+/*
  * If you're *only* going to link to new version bots (1.3.0 or higher)
  * then you can safely define this.
  */
 #undef NO_OLD_BOTNET
 
-/* 
+/*
  * Undefine this to completely disable context debugging.
  * WARNING: DO NOT send in bug reports if you undefine this!
  */
 #define DEBUG_CONTEXT
 
-/* 
- * define the maximum length a handle on the bot can be.
- * (standard is 9 characters long)
- * (DO NOT MAKE THIS VALUE LESS THAN 9 UNLESS YOU WANT TROUBLE!)
- * (beware that using lengths over 9 chars is 'non-standard' and if you
- * wish to link to other bots, they _must_ both have the same maximum
- * handle length)
+/*
+ * HANDLEN note:
+ *       HANDLEN defines the maximum length a handle on the bot can be.
+ *       Standard (and minimum) is 9 characters long.
+ *
+ *       Beware that using lengths over 9 chars is 'non-standard' and if
+ *       you wish to link to other bots, they _must_ both have the same
+ *       maximum handle length.
+ *
+ * NICKMAX note:
+ *       You should leave this at 32 characters and modify nick-len in the
+ *       configuration file instead.
  */
 
-/* handy string lengths */
+#define HANDLEN		  9	/* valid values 9->NICKMAX		*/
+#define NICKMAX		 32	/* valid values HANDLEN->32		*/
 
-#define HANDLEN		9	/* valid values 9->NICKMAX */
-#define BADHANDCHARS  "-,+*=:!.@#;$%&"
-#define NICKMAX        9	/* valid values HANDLEN->32 */
-#define UHOSTMAX     160        /* reasonable, i think? */
-#define DIRMAX       256	/* paranoia */
-#define MAX_LOG_LINE 767	/* for misc.c/putlog() <cybah> */
 
-/* language stuff */
+/* Handy string lengths */
 
-#define LANGDIR	"./language"	/* language file directory */
-#define BASELANG "english"	/* language which always gets loaded before
-				   all other languages. You don't want to
-				   change this. */
+#define UHOSTMAX	160	/* reasonable, i think?			*/
+#define DIRMAX		256	/* paranoia				*/
+#define LOGLINEMAX	767	/* for misc.c/putlog() <cybah>		*/
+#define BADHANDCHARS	"-,+*=:!.@#;$%&"
 
-/***********************************************************************/
-/***** the 'configure' script should make this next part automatic *****/
-/***********************************************************************/
+
+/* Language stuff */
+
+#define LANGDIR	"./language"	/* language file directory		*/
+#define BASELANG "english"	/* language which always gets loaded
+				   before all other languages. You do
+				   not want to change this.		*/
+
+
+/*
+ *     The 'configure' script should make this next part automatic,
+ *     so you shouldn't need to adjust anything below.
+ */
 
 #define NICKLEN         NICKMAX + 1
 #define UHOSTLEN        UHOSTMAX + 1
 #define DIRLEN          DIRMAX + 1
+#define LOGLINELEN	LOGLINEMAX + 1
 #define NOTENAMELEN     ((HANDLEN * 2) + 1)
-#define BADNICKCHARS "-,+*=:!.@#;$%&"
+#define BADNICKCHARS	"-,+*=:!.@#;$%&"
+
 
-/* have to use a weird way to make the compiler error out cos not all
- * compilers support #error or error */
+/* Have to use a weird way to make the compiler error out cos not all
+ * compilers support #error or error
+ */
 #if !HAVE_VSPRINTF
-#include "error_you_need_vsprintf_to_compile_eggdrop"
+#  include "error_you_need_vsprintf_to_compile_eggdrop"
 #endif
 
 #if HAVE_UNISTD_H
-#include <unistd.h>
+#  include <unistd.h>
 #endif
 
 #ifndef STATIC
-#if (!defined(MODULES_OK) || !defined(HAVE_DLOPEN)) && !defined(HPUX_HACKS)
-#include "you_can't_compile_with_module_support_on_this_system_try_make_static"
-#endif
+#  if (!defined(MODULES_OK) || !defined(HAVE_DLOPEN)) && !defined(HPUX_HACKS)
+#    include "you_can't_compile_with_module_support_on_this_system_try_make_static"
+#  endif
 #endif
 
 #if !defined(STDC_HEADERS)
-#include "you_need_to_upgrade_your_compiler_to_a_standard_c_one_mate!"
+#  include "you_need_to_upgrade_your_compiler_to_a_standard_c_one_mate!"
 #endif
 
 #if (NICKMAX < 9) || (NICKMAX > 32)
-#include "invalid NICKMAX value"
+#  include "invalid NICKMAX value"
 #endif
 
 #if (HANDLEN < 9) || (HANDLEN > 32)
-#include "invalid HANDLEN value"
+#  include "invalid HANDLEN value"
 #endif
 
 #if HANDLEN > NICKMAX
-#include "HANDLEN MUST BE <= NICKMAX"
+#  include "HANDLEN MUST BE <= NICKMAX"
 #endif
 
-/* almost every module needs some sort of time thingy, so... */
+/* NAME_MAX is what POSIX defines, but BSD calls it MAXNAMLEN.
+ * Use 255 if we can't find anything else.
+ */
+#ifndef NAME_MAX
+#  ifdef MAXNAMLEN
+#    define NAME_MAX	MAXNAMLEN
+#  else
+#    define NAME_MAX	255
+#  endif
+#endif
+
+/* Almost every module needs some sort of time thingy, so... */
 #if TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#include <time.h>
-#else
-#if HAVE_SYS_TIME_H
-#include <sys/time.h>
+#  include <sys/time.h>
+#  include <time.h>
 #else
-#include <time.h>
-#endif
+#  if HAVE_SYS_TIME_H
+#    include <sys/time.h>
+#  else
+#    include <time.h>
+#  endif
 #endif
 
 #if !HAVE_SRANDOM
-#define srandom(x) srand(x)
+#  define srandom(x) srand(x)
 #endif
 
 #if !HAVE_RANDOM
-#define random() (rand()/16)
+#  define random() (rand()/16)
 #endif
 
 #if !HAVE_SIGACTION		/* old "weird signals" */
-#define sigaction sigvec
-#ifndef sa_handler
-#define sa_handler sv_handler
-#define sa_mask sv_mask
-#define sa_flags sv_flags
-#endif
+#  define sigaction sigvec
+#  ifndef sa_handler
+#    define sa_handler sv_handler
+#    define sa_mask sv_mask
+#    define sa_flags sv_flags
+#  endif
 #endif
 
 #if !HAVE_SIGEMPTYSET
 /* and they probably won't have sigemptyset, dammit */
-#define sigemptyset(x) ((*(int *)(x))=0)
+#  define sigemptyset(x) ((*(int *)(x))=0)
 #endif
 
-/* handy aliases for memory tracking and core dumps */
-#define nmalloc(x) n_malloc((x),__FILE__,__LINE__)
-#define nrealloc(x,y) n_realloc((x),(y),__FILE__,__LINE__)
-#define nfree(x) n_free((x),__FILE__,__LINE__)
+
+/*
+ *    Handy aliases for memory tracking and core dumps
+ */
+
+#define nmalloc(x)	n_malloc((x),__FILE__,__LINE__)
+#define nrealloc(x,y)	n_realloc((x),(y),__FILE__,__LINE__)
+#define nfree(x)	n_free((x),__FILE__,__LINE__)
 
 #ifdef DEBUG_CONTEXT
-#  define Context eggContext(__FILE__, __LINE__, NULL)
-#  define ContextNote(note) eggContextNote(__FILE__, __LINE__, NULL, note)
+#  define Context		eggContext(__FILE__, __LINE__, NULL)
+#  define ContextNote(note)	eggContextNote(__FILE__, __LINE__, NULL, note)
 #else
-#  define Context {}
-#  define ContextNote(note) {}
+#  define Context		{}
+#  define ContextNote(note)	{}
 #endif
 
 #ifdef DEBUG_ASSERT
-#  define Assert(expr) eggAssert(__FILE__, __LINE__, NULL, (int)(expr))
+#  define Assert(expr)	do {						\
+	if (!(expr))							\
+		eggAssert(__FILE__, __LINE__, NULL);			\
+} while (0)
 #else
-#  define Assert(expr) {}
+#  define Assert(expr)	do {	} while (0)
 #endif
 
-#undef malloc
-#define malloc(x) dont_use_old_malloc(x)
-#undef free
-#define free(x) dont_use_old_free(x)
+#ifndef COMPILING_MEM
+#  undef malloc
+#  define malloc(x)	dont_use_old_malloc(x)
+#  undef free
+#  define free(x)	dont_use_old_free(x)
+#endif /* !COMPILING_MEM */
 
 /* 32 bit type */
 #if (SIZEOF_INT == 4)
-typedef unsigned int u_32bit_t;
+typedef unsigned int		u_32bit_t;
 #else
-# if (SIZEOF_LONG == 4)
-typedef unsigned int u_32bit_t;
-# else
-#  include "cant/find/32bit/type"
-# endif
+#  if (SIZEOF_LONG == 4)
+typedef unsigned long		u_32bit_t;
+#  else
+#    include "cant/find/32bit/type"
+#  endif
 #endif
 
-#if (SIZEOF_SHORT_INT == 2)
-typedef unsigned short int u_16bit_t;
-#else
-# include "cant/find/16bit/type"
-#endif
-
-#if (SIZEOF_CHAR == 1)
-typedef unsigned char u_8bit_t;
-#else
-# include "cant/find/8bit/type"
-#endif
-
-typedef u_8bit_t byte;
-typedef u_16bit_t word;
-typedef u_32bit_t dword;
+typedef unsigned short int	u_16bit_t;
+typedef unsigned char		u_8bit_t;
 
 /* IP type */
-typedef u_32bit_t IP;
+typedef u_32bit_t		IP;
 
-#define debug0(x) putlog(LOG_DEBUG,"*",x)
-#define debug1(x,a1) putlog(LOG_DEBUG,"*",x,a1)
-#define debug2(x,a1,a2) putlog(LOG_DEBUG,"*",x,a1,a2)
-#define debug3(x,a1,a2,a3) putlog(LOG_DEBUG,"*",x,a1,a2,a3)
-#define debug4(x,a1,a2,a3,a4) putlog(LOG_DEBUG,"*",x,a1,a2,a3,a4)
+#define debug0(x)		putlog(LOG_DEBUG,"*",x)
+#define debug1(x,a1)		putlog(LOG_DEBUG,"*",x,a1)
+#define debug2(x,a1,a2)		putlog(LOG_DEBUG,"*",x,a1,a2)
+#define debug3(x,a1,a2,a3)	putlog(LOG_DEBUG,"*",x,a1,a2,a3)
+#define debug4(x,a1,a2,a3,a4)	putlog(LOG_DEBUG,"*",x,a1,a2,a3,a4)
 
 /***********************************************************************/
 
-/* public structure for the listening port map */
+/* It's used in so many places, let's put it here */
+typedef int (*Function) ();
+
+/* Public structure for the listening port map */
 struct portmap {
   int realport;
   int mappedto;
   struct portmap *next;
 };
 
-/* public structure of all the dcc connections */
+/* Public structure of all the dcc connections */
 struct dcc_table {
   char *name;
   int flags;
@@ -222,23 +245,24 @@ struct dcc_table {
   int (*expmem) (void *);
   void (*kill) (int, void *);
   void (*output) (int, char *, void *);
+  void (*outdone) (int);
 };
 
 struct userrec;
 
 struct dcc_t {
-  long sock;			/* this should be a long to keep 64-bit
-				 * machines sane */
-  IP addr;			/* IP address in host byte order */
+  long sock;			/* This should be a long to keep 64-bit
+				   machines sane			 */
+  IP addr;			/* IP address in host byte order	 */
   unsigned int port;
   struct userrec *user;
   char nick[NICKLEN];
   char host[UHOSTLEN];
   struct dcc_table *type;
-  time_t timeval;		/* use for any timing stuff 
-				 * - this is used for timeout checking */
-  unsigned long status;		/* A LOT of dcc types have status thingos,
-				 * this makes it more avaliabe */
+  time_t timeval;		/* Use for any timing stuff
+				   - this is used for timeout checking	*/
+  unsigned long status;		/* A LOT of dcc types have status
+				   thingos, this makes it more avaliabe	*/
   union {
     struct chat_info *chat;
     struct file_info *file;
@@ -247,22 +271,25 @@ struct dcc_t {
     struct bot_info *bot;
     struct relay_info *relay;
     struct script_info *script;
+    struct dns_info *dns;
+    struct dupwait_info *dupwait;
     int ident_sock;
     void *other;
-  } u;				/* special use depending on type */
+  } u;				/* Special use depending on type	*/
 };
 
 struct chat_info {
-  char *away;			/* non-NULL if user is away */
-  int msgs_per_sec;		/* used to stop flooding */
-  int con_flags;		/* with console: what to show */
-  int strip_flags;		/* what codes to strip (b,r,u,c,a,g,*) */
-  char con_chan[81];		/* with console: what channel to view */
-  int channel;			/* 0=party line, -1=off */
-  struct msgq *buffer;		/* a buffer of outgoing lines (for .page cmd) */
-  int max_line;			/* maximum lines at once */
-  int line_count;		/* number of lines sent since last page */
-  int current_lines;		/* number of lines total stored */
+  char *away;			/* non-NULL if user is away		*/
+  int msgs_per_sec;		/* used to stop flooding		*/
+  int con_flags;		/* with console: what to show		*/
+  int strip_flags;		/* what codes to strip (b,r,u,c,a,g,*)	*/
+  char con_chan[81];		/* with console: what channel to view	*/
+  int channel;			/* 0=party line, -1=off			*/
+  struct msgq *buffer;		/* a buffer of outgoing lines
+				   (for .page cmd)			*/
+  int max_line;			/* maximum lines at once		*/
+  int line_count;		/* number of lines sent since last page	*/
+  int current_lines;		/* number of lines total stored		*/
   char *su_nick;
 };
 
@@ -272,21 +299,46 @@ struct file_info {
 };
 
 struct xfer_info {
-  char filename[121];
+  char *filename;
+  char *origname;
   char dir[121];		/* used when uploads go to the current dir */
   unsigned long length;
   unsigned long acked;
-  char buf[4];			/* you only need 5 bytes! */
-  unsigned char sofar;		/* how much of the byte count received */
-  char from[NICKLEN];		/* [GET] user who offered the file */
-  FILE *f;			/* pointer to file being sent/received */
+  char buf[4];			/* you only need 5 bytes!		   */
+  unsigned char sofar;		/* how much of the byte count received	   */
+  char from[NICKLEN];		/* [GET] user who offered the file	   */
+  FILE *f;			/* pointer to file being sent/received	   */
+  unsigned int type;		/* xfer connection type, see enum below	   */
+  unsigned short ack_type;	/* type of ack				   */
+  unsigned long offset;		/* offset from beginning of file, during
+				   resend.				   */
+  unsigned long block_pending;	/* bytes of this DCC block which weren't
+				   sent yet.				   */
+  time_t start_time;		/* Time when a xfer was started.	   */
+};
+
+enum {				/* transfer connection handling a ...	*/
+	XFER_SEND,		/*  ... normal file-send to s.o.	*/
+	XFER_RESEND,		/*  ... file-resend to s.o.		*/
+	XFER_RESEND_PEND,	/*  ... (as above) and waiting for info	*/
+	XFER_RESUME,		/*  ... file-send-resume to s.o.	*/
+	XFER_RESUME_PEND,	/*  ... (as above) and waiting for conn */
+	XFER_GET		/*  ... file-get from s.o.		*/
+};
+
+enum {
+	XFER_ACK_UNKNOWN,	/* We don't know how blocks are acked.	*/
+	XFER_ACK_WITH_OFFSET,	/* Skipped data is also counted as
+				   received.				*/
+	XFER_ACK_WITHOUT_OFFSET	/* Skipped data is NOT counted in ack.	*/
 };
 
 struct bot_info {
-  char version[121];		/* channel/version info */
-  char linker[NOTENAMELEN + 1];	/* who requested this link */
-  int numver;
-  int port;			/* base port */
+  char version[121];		/* channel/version info			*/
+  char linker[NOTENAMELEN + 1];	/* who requested this link		*/
+  int  numver;
+  int  port;			/* base port				*/
+  int  uff_flags;		/* user file feature flags		*/
 };
 
 struct relay_info {
@@ -306,54 +358,88 @@ struct script_info {
   char command[121];
 };
 
-/* flags about dcc types */
-#define DCT_CHAT      0x00000001	/* this dcc type receives botnet chatter */
-#define DCT_MASTER    0x00000002	/* received master chatter */
-#define DCT_SHOWWHO   0x00000004	/* show the user in .who */
-#define DCT_REMOTEWHO 0x00000008	/* show in remote who */
-#define DCT_VALIDIDX  0x00000010	/* valid idx for outputting to in tcl */
-#define DCT_SIMUL     0x00000020	/* can be tcl_simul'd */
-#define DCT_CANBOOT   0x00000040	/* can be booted */
-#define DCT_GETNOTES  DCT_CHAT	/* can receive notes */
-#define DCT_FILES     0x00000080	/* gratuitous hack ;) */
-#define DCT_FORKTYPE  0x00000100	/* a forking type */
+struct dns_info {
+  void (*dns_success)(int);	/* is called if the dns request succeeds   */
+  void (*dns_failure)(int);	/* is called if it fails		   */
+  char *host;			/* hostname				   */
+  char *cbuf;			/* temporary buffer. Memory will be free'd
+				   as soon as dns_info is free'd	   */
+  char *cptr;			/* temporary pointer			   */
+  IP ip;			/* IP address				   */
+  int ibuf;			/* temporary buffer for one integer	   */
+  char dns_type;		/* lookup type, e.g. RES_HOSTBYIP	   */
+  struct dcc_table *type;	/* type of the dcc table we are making the
+				   lookup for				   */
+};
+
+/* Flags for dns_type
+ */
+#define RES_HOSTBYIP  1		/* hostname to IP address		*/
+#define RES_IPBYHOST  2		/* IP address to hostname		*/
+
+struct dupwait_info {
+  int atr;			/* the bots attributes			*/
+  struct chat_info *chat;	/* holds current chat data		*/
+};
+
+/* Flags about dcc types
+ */
+#define DCT_CHAT      0x00000001	/* this dcc type receives botnet
+					   chatter			    */
+#define DCT_MASTER    0x00000002	/* received master chatter	    */
+#define DCT_SHOWWHO   0x00000004	/* show the user in .who	    */
+#define DCT_REMOTEWHO 0x00000008	/* show in remote who		    */
+#define DCT_VALIDIDX  0x00000010	/* valid idx for outputting to
+					   in tcl			    */
+#define DCT_SIMUL     0x00000020	/* can be tcl_simul'd		    */
+#define DCT_CANBOOT   0x00000040	/* can be booted		    */
+#define DCT_GETNOTES  DCT_CHAT		/* can receive notes		    */
+#define DCT_FILES     0x00000080	/* gratuitous hack ;)		    */
+#define DCT_FORKTYPE  0x00000100	/* a forking type		    */
 #define DCT_BOT       0x00000200	/* a bot connection of some sort... */
-#define DCT_FILETRAN  0x00000400	/* a file transfer of some sort */
-#define DCT_FILESEND  0x00000800	/* a sending file transfer, getting = !this */
-#define DCT_LISTEN    0x00001000	/* a listening port of some sort */
-
-/* for dcc chat & files: */
-#define STAT_ECHO    1		/* echo commands back? */
-#define STAT_DENY    2		/* bad username (ignore password & deny access) */
-/*#define STAT_XFER    4       has 'x' flag on chat line */
-#define STAT_CHAT    8		/* in file-system but may return */
-#define STAT_TELNET  16		/* connected via telnet */
-#define STAT_PARTY   32		/* only on party line via 'p' flag */
-#define STAT_BOTONLY 64		/* telnet on bots-only connect */
-#define STAT_USRONLY 128	/* telnet on users-only connect */
-#define STAT_PAGE    256	/* page output to the user */
-
-/* for stripping out mIRC codes */
-#define STRIP_COLOR  1		/* remove mIRC color codes */
-#define STRIP_BOLD   2		/* remove bold codes */
-#define STRIP_REV    4		/* remove reverse video codes */
-#define STRIP_UNDER  8		/* remove underline codes */
-#define STRIP_ANSI   16		/* remove ALL ansi codes */
-#define STRIP_BELLS  32		/* remote ctrl-g's */
-#define STRIP_ALL    63		/* remove every damn thing! */
+#define DCT_FILETRAN  0x00000400	/* a file transfer of some sort	    */
+#define DCT_FILESEND  0x00000800	/* a sending file transfer,
+					   getting = !this		    */
+#define DCT_LISTEN    0x00001000	/* a listening port of some sort    */
+
+/* For dcc chat & files:
+ */
+#define STAT_ECHO    0x00001	/* echo commands back?			*/
+#define STAT_DENY    0x00002	/* bad username (ignore password & deny
+				   access)				*/
+#define STAT_CHAT    0x00004	/* in file-system but may return	*/
+#define STAT_TELNET  0x00008	/* connected via telnet			*/
+#define STAT_PARTY   0x00010	/* only on party line via 'p' flag	*/
+#define STAT_BOTONLY 0x00020	/* telnet on bots-only connect		*/
+#define STAT_USRONLY 0x00040	/* telnet on users-only connect		*/
+#define STAT_PAGE    0x00080	/* page output to the user		*/
+
+/* For stripping out mIRC codes
+ */
+#define STRIP_COLOR  0x00001	/* remove mIRC color codes		*/
+#define STRIP_BOLD   0x00002	/* remove bold codes			*/
+#define STRIP_REV    0x00004	/* remove reverse video codes		*/
+#define STRIP_UNDER  0x00008	/* remove underline codes		*/
+#define STRIP_ANSI   0x00010	/* remove ALL ansi codes		*/
+#define STRIP_BELLS  0x00020	/* remote ctrl-g's			*/
+#define STRIP_ALL    0x00040	/* remove every damn thing!		*/
 
 /* for dcc bot links: */
-#define STAT_PINGED  0x01	/* waiting for ping to return */
-#define STAT_SHARE   0x02	/* sharing user data with the bot */
-#define STAT_CALLED  0x04	/* this bot called me */
-#define STAT_OFFERED 0x08	/* offered her the user file */
-#define STAT_SENDING 0x10	/* in the process of sending a user list */
-#define STAT_GETTING 0x20	/* in the process of getting a user list */
-#define STAT_WARNED  0x40	/* warned him about unleaflike behavior */
-#define STAT_LEAF    0x80	/* this bot is a leaf only */
-#define STAT_LINKING 0x100	/* the bot is currently going through the
-				 * linking stage */
-#define STAT_AGGRESSIVE 0x200	/* aggressively sharing with this bot */
+#define STAT_PINGED  0x00001	/* waiting for ping to return		 */
+#define STAT_SHARE   0x00002	/* sharing user data with the bot	 */
+#define STAT_CALLED  0x00004	/* this bot called me			 */
+#define STAT_OFFERED 0x00008	/* offered her the user file		 */
+#define STAT_SENDING 0x00010	/* in the process of sending a user list */
+#define STAT_GETTING 0x00020	/* in the process of getting a user list */
+#define STAT_WARNED  0x00040	/* warned him about unleaflike behavior  */
+#define STAT_LEAF    0x00080	/* this bot is a leaf only		 */
+#define STAT_LINKING 0x00100	/* the bot is currently going through
+				   the linking stage			 */
+#define STAT_AGGRESSIVE   0x200	/* aggressively sharing with this bot	 */
+
+/* Flags for listening sockets
+ */
+#define LSTN_PUBLIC  0x000001	/* No access restrictions		*/
 
 /* chan & global */
 #define FLOOD_PRIVMSG    0
@@ -363,89 +449,109 @@ struct script_info {
 #define FLOOD_JOIN       4
 #define FLOOD_KICK       5
 #define FLOOD_DEOP       6
+
 #define FLOOD_CHAN_MAX   7
 #define FLOOD_GLOBAL_MAX 3
 
-/* for local console: */
+/* For local console: */
 #define STDIN      0
 #define STDOUT     1
 #define STDERR     2
 
-/* structure for internal logs */
+/* Structure for internal logs */
 typedef struct {
   char *filename;
-  unsigned int mask;		/* what to send to this log */
-  char *chname;			/* which channel */
-  char szLast[MAX_LOG_LINE + 1];	/* for 'Last message repeated n times'
-					 * stuff in misc.c/putlog() <cybah> */
-  int Repeats;			/* number of times szLast has been repeated */
-  unsigned int flags;		/* other flags <rtc> */
-  FILE *f;			/* existing file */
+  unsigned int mask;		/* what to send to this log		    */
+  char *chname;			/* which channel			    */
+  char szlast[LOGLINELEN];	/* for 'Last message repeated n times'
+				   stuff in misc.c/putlog() <cybah>	    */
+  int repeats;			/* number of times szLast has been repeated */
+  unsigned int flags;		/* other flags <rtc>			    */
+  FILE *f;			/* existing file			    */
 } log_t;
 
-/* logfile display flags */
-#define LOG_MSGS   0x000001	/* m   msgs/notice/ctcps */
-#define LOG_PUBLIC 0x000002	/* p   public msg/notice/ctcps */
-#define LOG_JOIN   0x000004	/* j   channel joins/parts/etc */
-#define LOG_MODES  0x000008	/* k   mode changes/kicks/bans */
-#define LOG_CMDS   0x000010	/* c   user dcc or msg commands */
-#define LOG_MISC   0x000020	/* o   other misc bot things */
-#define LOG_BOTS   0x000040	/* b   bot notices */
-#define LOG_RAW    0x000080	/* r   raw server stuff coming in */
-#define LOG_FILES  0x000100	/* x   file transfer commands and stats */
-#define LOG_LEV1   0x000200	/* 1   user log level */
-#define LOG_LEV2   0x000400	/* 2   user log level */
-#define LOG_LEV3   0x000800	/* 3   user log level */
-#define LOG_LEV4   0x001000	/* 4   user log level */
-#define LOG_LEV5   0x002000	/* 5   user log level */
-#define LOG_LEV6   0x004000	/* 6   user log level */
-#define LOG_LEV7   0x008000	/* 7   user log level */
-#define LOG_LEV8   0x010000	/* 8   user log level */
-#define LOG_SERV   0x020000	/* s   server information */
-#define LOG_DEBUG  0x040000	/* d   debug */
-#define LOG_WALL   0x080000	/* w   wallops */
-#define LOG_SRVOUT 0x100000	/* v   server output */
-#define LOG_BOTNET 0x200000	/* t   botnet traffic */
-#define LOG_BOTSHARE 0x400000	/* h   share traffic */
-#define LOG_ALL    0x7fffff	/* (dump to all logfiles) */
-/* internal logfile flags */
-#define LF_EXPIRING 0x000001	/* Logfile will be closed soon */
+/* Logfile display flags
+ */
+#define LOG_MSGS     0x000001	/* m   msgs/notice/ctcps		*/
+#define LOG_PUBLIC   0x000002	/* p   public msg/notice/ctcps		*/
+#define LOG_JOIN     0x000004	/* j   channel joins/parts/etc		*/
+#define LOG_MODES    0x000008	/* k   mode changes/kicks/bans		*/
+#define LOG_CMDS     0x000010	/* c   user dcc or msg commands		*/
+#define LOG_MISC     0x000020	/* o   other misc bot things		*/
+#define LOG_BOTS     0x000040	/* b   bot notices			*/
+#define LOG_RAW      0x000080	/* r   raw server stuff coming in	*/
+#define LOG_FILES    0x000100	/* x   file transfer commands and stats	*/
+#define LOG_LEV1     0x000200	/* 1   user log level			*/
+#define LOG_LEV2     0x000400	/* 2   user log level			*/
+#define LOG_LEV3     0x000800	/* 3   user log level			*/
+#define LOG_LEV4     0x001000	/* 4   user log level			*/
+#define LOG_LEV5     0x002000	/* 5   user log level			*/
+#define LOG_LEV6     0x004000	/* 6   user log level			*/
+#define LOG_LEV7     0x008000	/* 7   user log level			*/
+#define LOG_LEV8     0x010000	/* 8   user log level			*/
+#define LOG_SERV     0x020000	/* s   server information		*/
+#define LOG_DEBUG    0x040000	/* d   debug				*/
+#define LOG_WALL     0x080000	/* w   wallops				*/
+#define LOG_SRVOUT   0x100000	/* v   server output			*/
+#define LOG_BOTNET   0x200000	/* t   botnet traffic			*/
+#define LOG_BOTSHARE 0x400000	/* h   share traffic			*/
+#define LOG_ALL      0x7fffff	/* (dump to all logfiles)		*/
+
+/* Internal logfile flags
+ */
+#define LF_EXPIRING 0x000001	/* Logfile will be closed soon		*/
 
 #define FILEDB_HIDE     1
 #define FILEDB_UNHIDE   2
 #define FILEDB_SHARE    3
 #define FILEDB_UNSHARE  4
 
-/* socket flags: */
-#define SOCK_UNUSED     0x001	/* empty socket */
-#define SOCK_BINARY     0x002	/* do not buffer input */
-#define SOCK_LISTEN     0x004	/* listening port */
-#define SOCK_CONNECT    0x008	/* connection attempt */
-#define SOCK_NONSOCK    0x010	/* used for file i/o on debug */
-#define SOCK_STRONGCONN 0x020	/* don't report success until sure */
-#define SOCK_EOFD       0x040	/* it EOF'd recently during a write */
-#define SOCK_PROXYWAIT	0x080	/* waiting for SOCKS traversal */
-
-/* fake idx's for dprintf - these should be ridiculously large +ve nums */
+/* Socket flags:
+ */
+#define SOCK_UNUSED     0x0001	/* empty socket				*/
+#define SOCK_BINARY     0x0002	/* do not buffer input			*/
+#define SOCK_LISTEN     0x0004	/* listening port			*/
+#define SOCK_CONNECT    0x0008	/* connection attempt			*/
+#define SOCK_NONSOCK    0x0010	/* used for file i/o on debug		*/
+#define SOCK_STRONGCONN 0x0020	/* don't report success until sure	*/
+#define SOCK_EOFD       0x0040	/* it EOF'd recently during a write	*/
+#define SOCK_PROXYWAIT	0x0080	/* waiting for SOCKS traversal		*/
+#define SOCK_PASS	0x0100	/* passed on; only notify in case
+				   of traffic				*/
+#define SOCK_VIRTUAL	0x0200	/* not-connected socket (dont read it!)	*/
+#define SOCK_BUFFER	0x0400	/* buffer data; don't notify dcc funcs	*/
+
+/* Flags to sock_has_data
+ */
+enum {
+  SOCK_DATA_OUTGOING,		/* Data in out-queue?			*/
+  SOCK_DATA_INCOMING		/* Data in in-queue?			*/
+};
+
+/* Fake idx's for dprintf - these should be ridiculously large +ve nums
+ */
 #define DP_STDOUT       0x7FF1
 #define DP_LOG          0x7FF2
 #define DP_SERVER       0x7FF3
 #define DP_HELP         0x7FF4
 #define DP_STDERR       0x7FF5
 #define DP_MODE         0x7FF6
+#define DP_MODE_NEXT    0x7FF7
+#define DP_SERVER_NEXT  0x7FF8
+#define DP_HELP_NEXT    0x7FF9
 
 #define NORMAL          0
 #define QUICK           1
 
-/* return codes for add_note */
-#define NOTE_ERROR      0	/* error */
-#define NOTE_OK         1	/* success */
-#define NOTE_STORED     2	/* not online; stored */
-#define NOTE_FULL       3	/* too many notes stored */
-#define NOTE_TCL        4	/* tcl binding caught it */
-#define NOTE_AWAY       5	/* away; stored */
-#define NOTE_FWD        6	/* away; forwarded */
-#define NOTE_REJECT     7	/* ignore mask matched */
+/* Return codes for add_note */
+#define NOTE_ERROR      0	/* error			*/
+#define NOTE_OK         1	/* success			*/
+#define NOTE_STORED     2	/* not online; stored		*/
+#define NOTE_FULL       3	/* too many notes stored	*/
+#define NOTE_TCL        4	/* tcl binding caught it	*/
+#define NOTE_AWAY       5	/* away; stored			*/
+#define NOTE_FWD        6	/* away; forwarded		*/
+#define NOTE_REJECT     7	/* ignore mask matched		*/
 
 #define STR_PROTECT     2
 #define STR_DIR         1
@@ -454,17 +560,41 @@ typedef struct {
 #define HELP_TEXT       2
 #define HELP_IRC        16
 
-/* it's used in so many places, let's put it here */
-typedef int (*Function) ();
-
-/* this is used by the net module to keep track of sockets and what's
- * queued on them */
+/* This is used by the net module to keep track of sockets and what's
+ * queued on them
+ */
 typedef struct {
-  int sock;
-  char flags;
-  char *inbuf;
-  char *outbuf;
-  unsigned long outbuflen;	/* outbuf could be binary data */
+  int		 sock;
+  short		 flags;
+  char		*inbuf;
+  char		*outbuf;
+  unsigned long  outbuflen;	/* Outbuf could be binary data	*/
+  unsigned long	 inbuflen;	/* Inbuf could be binary data	*/
 } sock_list;
 
+enum {
+  EGG_OPTION_SET	= 1,	/* Set option(s).		*/
+  EGG_OPTION_UNSET	= 2	/* Unset option(s).		*/
+};
+
+/* Telnet codes.  See "TELNET Protocol Specification" (RFC 854) and
+ * "TELNET Echo Option" (RFC 875) for details.
+ */
+
+#define TLN_AYT		246		/* Are You There	*/
+
+#define TLN_WILL	251		/* Will			*/
+#define TLN_WILL_C	"\373"
+#define TLN_WONT	252		/* Won't		*/
+#define TLN_WONT_C	"\374"
+#define TLN_DO		253		/* Do			*/
+#define TLN_DO_C	"\375"
+#define TLN_DONT	254		/* Don't		*/
+#define TLN_DONT_C	"\376"
+#define TLN_IAC		255		/* Interpret As Command	*/
+#define TLN_IAC_C	"\377"
+
+#define TLN_ECHO	1		/* Echo			*/
+#define TLN_ECHO_C	"\001"
+
 #endif				/* _EGG_EGGDROP_H */

+ 84 - 77
src/flags.c

@@ -1,23 +1,23 @@
-/* 
+/*
  * flags.c -- handles:
  *   all the flag matching/conversion functions in one neat package :)
- * 
- * $Id: flags.c,v 1.9 2000/01/17 16:14:45 per Exp $
+ *
+ * $Id: flags.c,v 1.20 2002/06/13 20:43:07 wcc Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -25,10 +25,13 @@
 
 #include "main.h"
 
-extern int use_console_r, debug_output, require_p, noshare, allow_dk_cmds;
-extern struct dcc_t *dcc;
 
-int use_console_r = 0;		/* allow users to set their console +r */
+extern int		 use_console_r, debug_output, require_p, noshare,
+			 allow_dk_cmds;
+extern struct dcc_t	*dcc;
+
+int	use_console_r = 0;	/* Allow users to set their console +r	*/
+
 
 int logmodes(char *s)
 {
@@ -130,7 +133,7 @@ int logmodes(char *s)
 
 char *masktype(int x)
 {
-  static char s[24];		/* change this if you change the levels */
+  static char s[24];		/* Change this if you change the levels */
   char *p = s;
 
   if (x & LOG_MSGS)
@@ -187,7 +190,7 @@ char *masktype(int x)
 
 char *maskname(int x)
 {
-  static char s[207];		/* change this if you change the levels */
+  static char s[207];		/* Change this if you change the levels */
   int i = 0;
 
   s[0] = 0;
@@ -244,7 +247,8 @@ char *maskname(int x)
   return s;
 }
 
-/* some flags are mutually exclusive -- this roots them out */
+/* Some flags are mutually exclusive -- this roots them out
+ */
 int sanity_check(int atr)
 {
   if ((atr & USER_BOT) &&
@@ -252,60 +256,71 @@ int sanity_check(int atr)
     atr &= ~(USER_PARTY | USER_MASTER | USER_COMMON | USER_OWNER);
   if ((atr & USER_OP) && (atr & USER_DEOP))
     atr &= ~(USER_OP | USER_DEOP);
+  if ((atr & USER_HALFOP) && (atr & USER_DEHALFOP))
+    atr &= ~(USER_HALFOP | USER_DEHALFOP);
   if ((atr & USER_AUTOOP) && (atr & USER_DEOP))
     atr &= ~(USER_AUTOOP | USER_DEOP);
+  if ((atr & USER_AUTOHALFOP) && (atr & USER_DEHALFOP))
+    atr &= ~(USER_AUTOHALFOP | USER_DEHALFOP);
   if ((atr & USER_VOICE) && (atr & USER_QUIET))
     atr &= ~(USER_VOICE | USER_QUIET);
   if ((atr & USER_GVOICE) && (atr & USER_QUIET))
     atr &= ~(USER_GVOICE | USER_QUIET);
-  /* can't be owner without also being master */
+  /* Can't be owner without also being master */
   if (atr & USER_OWNER)
     atr |= USER_MASTER;
-  /* master implies botmaster, op, friend and janitor */
+  /* Master implies botmaster, op and janitor */
   if (atr & USER_MASTER)
-    atr |= USER_BOTMAST | USER_OP | USER_FRIEND | USER_JANITOR;
-  /* can't be botnet master without party-line access */
+    atr |= USER_BOTMAST | USER_OP | USER_JANITOR;
+  /* Can't be botnet master without party-line access */
   if (atr & USER_BOTMAST)
     atr |= USER_PARTY;
-  /* janitors can use the file area */
+  /* Janitors can use the file area */
   if (atr & USER_JANITOR)
     atr |= USER_XFER;
   return atr;
 }
 
-/* sanity check on channel attributes */
+/* Sanity check on channel attributes
+ */
 int chan_sanity_check(int chatr, int atr)
 {
   if ((chatr & USER_OP) && (chatr & USER_DEOP))
     chatr &= ~(USER_OP | USER_DEOP);
+  if ((chatr & USER_HALFOP) && (chatr & USER_DEHALFOP))
+    chatr &= ~(USER_HALFOP | USER_DEHALFOP);
   if ((chatr & USER_AUTOOP) && (chatr & USER_DEOP))
     chatr &= ~(USER_AUTOOP | USER_DEOP);
+  if ((chatr & USER_AUTOHALFOP) && (chatr & USER_DEHALFOP))
+    chatr &= ~(USER_AUTOHALFOP | USER_DEHALFOP);
   if ((chatr & USER_VOICE) && (chatr & USER_QUIET))
     chatr &= ~(USER_VOICE | USER_QUIET);
   if ((chatr & USER_GVOICE) && (chatr & USER_QUIET))
     chatr &= ~(USER_GVOICE | USER_QUIET);
-  /* can't be channel owner without also being channel master */
+  /* Can't be channel owner without also being channel master */
   if (chatr & USER_OWNER)
     chatr |= USER_MASTER;
-  /* master implies friend & op */
+  /* Master implies op */
   if (chatr & USER_MASTER)
-    chatr |= USER_OP | USER_FRIEND;
-  /* can't be +s on chan unless you're a bot */
+    chatr |= USER_OP ;
+  /* Can't be +s on chan unless you're a bot */
   if (!(atr & USER_BOT))
     chatr &= ~BOT_SHARE;
   return chatr;
 }
 
-/* get icon symbol for a user (depending on access level)
- * (*)owner on any channel
- * (+)master on any channel
+/* Get icon symbol for a user (depending on access level)
+ *
+ * (*) owner on any channel
+ * (+) master on any channel
  * (%) botnet master
  * (@) op on any channel
- * (-) other */
+ * (^) halfop on any channel
+ * (-) other
+ */
 char geticon(int idx)
 {
-  struct flag_record fr =
-  {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
+  struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
 
   if (!dcc[idx].user)
     return '-';
@@ -318,15 +333,17 @@ char geticon(int idx)
     return '%';
   if (chan_op(fr))
     return '@';
+  if (chan_halfop(fr))
+    return '^';
   return '-';
 }
 
-void break_down_flags(char *string, struct flag_record *plus,
+void break_down_flags(const char *string, struct flag_record *plus,
 		      struct flag_record *minus)
 {
-  struct flag_record *which = plus;
-  int mode = 0;			/* 0 = glob, 1 = chan, 2 = bot */
-  int flags = plus->match;
+  struct flag_record	*which = plus;
+  int			 mode = 0;	/* 0 = glob, 1 = chan, 2 = bot */
+  int			 flags = plus->match;
 
   if (!(flags & FR_GLOBAL)) {
     if (flags & FR_BOT)
@@ -334,14 +351,14 @@ void break_down_flags(char *string, struct flag_record *plus,
     else if (flags & FR_CHAN)
       mode = 1;
     else
-      return;			/* we dont actually want any..huh? */
+      return;			/* We dont actually want any..huh? */
   }
-  bzero(plus, sizeof(struct flag_record));
+  egg_bzero(plus, sizeof(struct flag_record));
 
   if (minus)
-    bzero(minus, sizeof(struct flag_record));
+    egg_bzero(minus, sizeof(struct flag_record));
 
-  plus->match = FR_OR;		/* befault binding type OR */
+  plus->match = FR_OR;		/* Default binding type OR */
   while (*string) {
     switch (*string) {
     case '+':
@@ -352,7 +369,7 @@ void break_down_flags(char *string, struct flag_record *plus,
       break;
     case '|':
     case '&':
-      if (mode == 0) {
+      if (!mode) {
 	if (*string == '|')
 	  plus->match = FR_OR;
 	else
@@ -389,7 +406,7 @@ void break_down_flags(char *string, struct flag_record *plus,
 	}
       } else if ((*string >= '0') && (*string <= '9')) {
 	switch (mode) {
-	  /* map 0->9 to A->K for glob/chan so they are not lost */
+	  /* Map 0->9 to A->K for glob/chan so they are not lost */
 	case 0:
 	  which->udef_global |= 1 << (*string - '0');
 	  break;
@@ -523,7 +540,7 @@ int flagrec_ok(struct flag_record *req,
   } else if (req->match & FR_OR) {
     int hav = have->global;
 
-    /* exception 1 - global +d/+k cant use -|-, unless they are +p */
+    /* Exception 1 - global +d/+k cant use -|-, unless they are +p */
     if (!req->chan && !req->global && !req->udef_global &&
 	!req->udef_chan) {
       if (!allow_dk_cmds) {
@@ -536,8 +553,9 @@ int flagrec_ok(struct flag_record *req,
       }
       return 1;
     }
-    /* the +n/+m checks arent needed anymore since +n/+m
-     * automatically add lower flags */
+    /* The +n/+m checks arent needed anymore since +n/+m
+     * automatically add lower flags
+     */
     if (!require_p && ((hav & USER_OP) || (have->chan & USER_OWNER)))
       hav |= USER_PARTY;
     if (hav & req->global)
@@ -597,7 +615,7 @@ int flagrec_eq(struct flag_record *req, struct flag_record *have)
 }
 
 void set_user_flagrec(struct userrec *u, struct flag_record *fr,
-		      char *chname)
+		      const char *chname)
 {
   struct chanuserrec *cr = NULL;
   int oldflags = fr->match;
@@ -618,20 +636,19 @@ void set_user_flagrec(struct userrec *u, struct flag_record *fr,
   }
   if ((oldflags & FR_BOT) && (u->flags & USER_BOT))
     set_user(&USERENTRY_BOTFL, u, (void *) fr->bot);
-  /* dont share bot attrs */
+  /* Don't share bot attrs */
   if ((oldflags & FR_CHAN) && chname) {
     for (cr = u->chanrec; cr; cr = cr->next)
       if (!rfc_casecmp(chname, cr->channel))
 	break;
-    ch = findchan(chname);
+    ch = findchan_by_dname(chname);
     if (!cr && ch) {
       cr = user_malloc(sizeof(struct chanuserrec));
-      bzero(cr, sizeof(struct chanuserrec));
+      egg_bzero(cr, sizeof(struct chanuserrec));
 
       cr->next = u->chanrec;
       u->chanrec = cr;
-      strncpy(cr->channel, chname, 80);
-      cr->channel[80] = 0;
+      strncpyz(cr->channel, chname, sizeof cr->channel);
     }
     if (cr && ch) {
       cr->flags = fr->chan;
@@ -646,23 +663,22 @@ void set_user_flagrec(struct userrec *u, struct flag_record *fr,
   fr->match = oldflags;
 }
 
+/* Always pass the dname (display name) to this function for chname <cybah>
+ */
 void get_user_flagrec(struct userrec *u, struct flag_record *fr,
-		      char *chname)
+		      const char *chname)
 {
   struct chanuserrec *cr = NULL;
 
   if (!u) {
     fr->global = fr->udef_global = fr->chan = fr->udef_chan = fr->bot = 0;
-
     return;
   }
   if (fr->match & FR_GLOBAL) {
     fr->global = u->flags;
-
     fr->udef_global = u->flags_udef;
   } else {
     fr->global = 0;
-
     fr->udef_global = 0;
   }
   if (fr->match & FR_BOT) {
@@ -674,7 +690,7 @@ void get_user_flagrec(struct userrec *u, struct flag_record *fr,
       fr->chan = u->flags;
       fr->udef_chan = u->flags_udef;
       for (cr = u->chanrec; cr; cr = cr->next)
-	if (findchan(cr->channel)) {
+	if (findchan_by_dname(cr->channel)) {
 	  fr->chan |= cr->flags;
 	  fr->udef_chan |= cr->flags_udef;
 	}
@@ -683,7 +699,7 @@ void get_user_flagrec(struct userrec *u, struct flag_record *fr,
 	for (cr = u->chanrec; cr; cr = cr->next)
 	  if (!rfc_casecmp(chname, cr->channel))
 	    break;
-      if (chname && cr) {
+      if (cr) {
 	fr->chan = cr->flags;
 	fr->udef_chan = cr->flags_udef;
       } else {
@@ -697,10 +713,7 @@ void get_user_flagrec(struct userrec *u, struct flag_record *fr,
 static int botfl_unpack(struct userrec *u, struct user_entry *e)
 {
   struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
- 
-  Context;
-  Assert(e);
-  Assert(e->name);
+
   break_down_flags(e->u.list->extra, &fr, NULL);
   list_type_kill(e->u.list);
   e->u.ulong = fr.bot;
@@ -722,18 +735,16 @@ static int botfl_pack(struct userrec *u, struct user_entry *e)
 
 static int botfl_kill(struct user_entry *e)
 {
-  Context;
   nfree(e);
   return 1;
 }
 
-static int botfl_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
+static int botfl_write_userfile(FILE *f, struct userrec *u,
+				struct user_entry *e)
 {
   char x[100];
-  struct flag_record fr =
-  {FR_BOT, 0, 0, 0, 0, 0};
+  struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
 
-  Context;
   fr.bot = e->u.ulong;
   build_flags(x, &fr, NULL);
   if (fprintf(f, "--%s %s\n", e->type->name, x) == EOF)
@@ -745,9 +756,10 @@ static int botfl_set(struct userrec *u, struct user_entry *e, void *buf)
 {
   register long atr = ((long) buf & BOT_VALID);
 
-  Context;
   if (!(u->flags & USER_BOT))
-    return 1;			/* don't even bother trying to set the flags for a non-bot */
+    return 1;			/* Don't even bother trying to set the
+				   flags for a non-bot */
+
   if ((atr & BOT_HUB) && (atr & BOT_ALT))
     atr &= ~BOT_ALT;
   if (atr & BOT_REJECT) {
@@ -761,16 +773,14 @@ static int botfl_set(struct userrec *u, struct user_entry *e, void *buf)
   if (!(atr & BOT_SHARE))
     atr &= ~BOT_GLOBAL;
   e->u.ulong = atr;
-  Context;
   return 1;
 }
 
-static int botfl_tcl_get(Tcl_Interp * interp, struct userrec *u,
+static int botfl_tcl_get(Tcl_Interp *interp, struct userrec *u,
 			 struct user_entry *e, int argc, char **argv)
 {
   char x[100];
-  struct flag_record fr =
-  {FR_BOT, 0, 0, 0, 0, 0};
+  struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
 
   fr.bot = e->u.ulong;
   build_flags(x, &fr, NULL);
@@ -778,14 +788,14 @@ static int botfl_tcl_get(Tcl_Interp * interp, struct userrec *u,
   return TCL_OK;
 }
 
-static int botfl_tcl_set(Tcl_Interp * irp, struct userrec *u,
+static int botfl_tcl_set(Tcl_Interp *irp, struct userrec *u,
 			 struct user_entry *e, int argc, char **argv)
 {
   struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
 
   BADARGS(4, 4, " handle BOTFL flags");
   if (u->flags & USER_BOT) {
-    /* silently ignore for users */
+    /* Silently ignore for users */
     break_down_flags(argv[3], &fr, NULL);
     botfl_set(u, e, (void *) fr.bot);
   }
@@ -794,17 +804,14 @@ static int botfl_tcl_set(Tcl_Interp * irp, struct userrec *u,
 
 static int botfl_expmem(struct user_entry *e)
 {
-  Context;
   return 0;
 }
 
 static void botfl_display(int idx, struct user_entry *e)
 {
-  struct flag_record fr =
-  {FR_BOT, 0, 0, 0, 0, 0};
+  struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
   char x[100];
 
-  Context;
   fr.bot = e->u.ulong;
   build_flags(x, &fr, NULL);
   dprintf(idx, "  BOT FLAGS: %s\n", x);

+ 144 - 123
src/flags.h

@@ -1,22 +1,22 @@
-/* 
+/*
  * flags.h
- * 
- * $Id: flags.h,v 1.5 2000/01/08 21:23:14 per Exp $
+ *
+ * $Id: flags.h,v 1.10 2002/06/13 20:43:08 wcc Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -41,132 +41,153 @@ struct flag_record {
 #define FR_AND    0x20000000
 #define FR_ANYWH  0x10000000
 #define FR_ALL    0x0fffffff
-/* 
+
+/*
  * userflags:
- *             abcd?fgh?jk?mnopq??tuvwx??
- * + user defined A-Z
- *   unused letters: eilrsyz
- * 
+ *   abcdefgh?jklmnopqr?tuvwxyz
+ *   + user defined A-Z
+ *   unused letters: is
+ *
  * botflags:
  *   0123456789ab????ghi??l???p?rs???????
  *   unused letters: cdefjkmnoqtuvwxyz
- * 
+ *
  * chanflags:
- *             a??d?fg???k?mno?q?s?uv????
- * + user defined A-Z
- *   unused letters: bchijlprtwxyz
+ *   a??defg???klmno?qr??uv??yz
+ *   + user defined A-Z
+ *   unused letters: bchijpstwx
+ */
+#define USER_VALID 0x03fbfeff /* all USER_ flags in use              */
+#define CHAN_VALID 0x03777c79 /* all flags that can be chan specific */
+#define BOT_VALID  0x7fe689C1 /* all BOT_ flags in use               */
+
+
+#define USER_AUTOOP        0x00000001 /* a  auto-op                           */
+#define USER_BOT           0x00000002 /* b  user is a bot                     */
+#define USER_COMMON        0x00000004 /* c  user is actually a public site    */
+#define USER_DEOP          0x00000008 /* d  user is global de-op              */
+#define USER_EXEMPT        0x00000010 /* e  exempted from stopnethack         */
+#define USER_FRIEND        0x00000020 /* f  user is global friend             */
+#define USER_GVOICE        0x00000040 /* g  auto-voice                        */
+#define USER_HIGHLITE      0x00000080 /* h  highlighting (bold)               */
+#define USER_I             0x00000100 /* i  unused                            */
+#define USER_JANITOR       0x00000200 /* j  user is file area master          */
+#define USER_KICK          0x00000400 /* k  user is global auto-kick          */
+#define USER_HALFOP        0x00000800 /* l  user is +h on all channels        */
+#define USER_MASTER        0x00001000 /* m  user has full bot access          */
+#define USER_OWNER         0x00002000 /* n  user is the bot owner             */
+#define USER_OP            0x00004000 /* o  user is +o on all channels        */
+#define USER_PARTY         0x00008000 /* p  user has party line access        */
+#define USER_QUIET         0x00010000 /* q  user is global de-voice           */
+#define USER_DEHALFOP      0x00020000 /* r  user is global de-halfop          */
+#define USER_S             0x00040000 /* s  unused                            */
+#define USER_BOTMAST       0x00080000 /* t  user is botnet master             */
+#define USER_UNSHARED      0x00100000 /* u  not shared with sharebots         */
+#define USER_VOICE         0x00200000 /* v  user is +v on all channels        */
+#define USER_WASOPTEST     0x00400000 /* w  wasop test needed for stopnethack */
+#define USER_XFER          0x00800000 /* x  user has file area access         */
+#define USER_AUTOHALFOP    0x01000000 /* y  auto-halfop                       */
+#define USER_WASHALFOPTEST 0x02000000 /* z  washalfop test needed for
+                                            stopnethack                       */
+#define USER_DEFAULT       0x40000000 /* use default-flags                    */
+
+/* Flags specifically for bots
  */
-#define USER_VALID    0x00f9f6ef	/* all USER_ flags in use */
-#define CHAN_VALID    0x00757469	/* all flags that can be chan specific */
-#define BOT_VALID     0x7fe689C1	/* all BOT_ flags in use */
-
-#define USER_AUTOOP   0x00000001	/* a  auto-op */
-#define USER_BOT      0x00000002	/* b  user is a bot */
-#define USER_COMMON   0x00000004	/* c  user is actually a public irc
-					 * site */
-#define USER_DEOP     0x00000008	/* d  user is global de-op */
-#define USER_E        0x00000010	/* e  unused */
-#define USER_FRIEND   0x00000020	/* f  user is global friend */
-#define USER_GVOICE   0x00000040	/* g  give voice true auto */
-#define USER_HIGHLITE 0x00000080	/* h  highlighting (bold) */
-#define USER_I        0x00000100	/* i  unused */
-#define USER_JANITOR  0x00000200	/* j  user has file area master */
-#define USER_KICK     0x00000400	/* k  user is global auto-kick */
-#define USER_L        0x00000800	/* l  unused */
-#define USER_MASTER   0x00001000	/* m  user has full bot access */
-#define USER_OWNER    0x00002000	/* n  user is the bot owner */
-#define USER_OP       0x00004000	/* o  user is +o on all channels */
-#define USER_PARTY    0x00008000	/* p  user has party line access */
-#define USER_QUIET    0x00010000	/* q  never let 'em get a voice */
-#define USER_R        0x00020000	/* r  unused */
-#define USER_S        0x00040000	/* s  unused */
-#define USER_BOTMAST  0x00080000	/* t  user is botnet master */
-#define USER_UNSHARED 0x00100000	/* u  not shared with sharebots */
-#define USER_VOICE    0x00200000	/* v  auto-voice on join */
-#define USER_WASOPTEST 0x00400000	/* w  wasop test needed for
-					 * stopnethack */
-#define USER_XFER     0x00800000	/* x  user has file area access */
-#define USER_Y        0x01000000	/* y  unused */
-#define USER_Z        0x02000000	/* z  unused */
-#define USER_DEFAULT  0x40000000	/* use default-flags */
-
-/* flags specifically for bots */
-#define BOT_ALT       0x00000001	/* a  auto-link here if all +h's fail */
-#define BOT_BOT       0x00000002	/* b  sanity bot flag */
-#define BOT_C         0x00000004	/* c  unused */
-#define BOT_D         0x00000008	/* d  unused */
-#define BOT_E         0x00000010	/* e  unused */
-#define BOT_F         0x00000020	/* f  unused */
-#define BOT_GLOBAL    0x00000040	/* g  all channel are shared */
-#define BOT_HUB       0x00000080	/* h  auto-link to ONE of these bots */
-#define BOT_ISOLATE   0x00000100	/* i  isolate party line from botnet */
-#define BOT_J         0x00000200	/* j  unused */
-#define BOT_K         0x00000400	/* k  unused */
-#define BOT_LEAF      0x00000800	/* l  may not link other bots */
-#define BOT_M         0x00001000	/* m  unused */
-#define BOT_N         0x00002000	/* n  unused */
-#define BOT_O         0x00004000	/* o  unused */
-#define BOT_PASSIVE   0x00008000	/* p  share passively with this bot */
+#define BOT_ALT       0x00000001	/* a  auto-link here if all +h's
+					      fail			 */
+#define BOT_BOT       0x00000002	/* b  sanity bot flag		 */
+#define BOT_C         0x00000004	/* c  unused			 */
+#define BOT_D         0x00000008	/* d  unused			 */
+#define BOT_E         0x00000010	/* e  unused			 */
+#define BOT_F         0x00000020	/* f  unused			 */
+#define BOT_GLOBAL    0x00000040	/* g  all channel are shared	 */
+#define BOT_HUB       0x00000080	/* h  auto-link to ONE of these
+					      bots			 */
+#define BOT_ISOLATE   0x00000100	/* i  isolate party line from
+					      botnet			 */
+#define BOT_J         0x00000200	/* j  unused			 */
+#define BOT_K         0x00000400	/* k  unused			 */
+#define BOT_LEAF      0x00000800	/* l  may not link other bots	 */
+#define BOT_M         0x00001000	/* m  unused			 */
+#define BOT_N         0x00002000	/* n  unused			 */
+#define BOT_O         0x00004000	/* o  unused			 */
+#define BOT_PASSIVE   0x00008000	/* p  share passively with this
+					      bot			 */
 #define BOT_Q         0x00010000	/* q  unused */
-#define BOT_REJECT    0x00020000	/* r  automatically reject anywhere */
-#define BOT_AGGRESSIVE 0x00040000	/* s  bot shares user files */
-#define BOT_T         0x00080000	/* t  unused */
-#define BOT_U         0x00100000	/* u  unused */
-#define BOT_V         0x00200000	/* v  unused */
-#define BOT_W         0x00400000	/* w  unused */
-#define BOT_X         0x00800000	/* x  unused */
-#define BOT_Y         0x01000000	/* y  unused */
-#define BOT_Z         0x02000000	/* z  unused */
-#define BOT_FLAG0     0x00200000	/* 0  user-defined flag #0 */
-#define BOT_FLAG1     0x00400000	/* 1  user-defined flag #1 */
-#define BOT_FLAG2     0x00800000	/* 2  user-defined flag #2 */
-#define BOT_FLAG3     0x01000000	/* 3  user-defined flag #3 */
-#define BOT_FLAG4     0x02000000	/* 4  user-defined flag #4 */
-#define BOT_FLAG5     0x04000000	/* 5  user-defined flag #5 */
-#define BOT_FLAG6     0x08000000	/* 6  user-defined flag #6 */
-#define BOT_FLAG7     0x10000000	/* 7  user-defined flag #7 */
-#define BOT_FLAG8     0x20000000	/* 8  user-defined flag #8 */
-#define BOT_FLAG9     0x40000000	/* 9  user-defined flag #9 */
+#define BOT_REJECT    0x00020000	/* r  automatically reject
+					      anywhere			 */
+#define BOT_AGGRESSIVE 0x00040000	/* s  bot shares user files	 */
+#define BOT_T         0x00080000	/* t  unused			 */
+#define BOT_U         0x00100000	/* u  unused			 */
+#define BOT_V         0x00200000	/* v  unused			 */
+#define BOT_W         0x00400000	/* w  unused			 */
+#define BOT_X         0x00800000	/* x  unused			 */
+#define BOT_Y         0x01000000	/* y  unused			 */
+#define BOT_Z         0x02000000	/* z  unused			 */
+#define BOT_FLAG0     0x00200000	/* 0  user-defined flag #0	 */
+#define BOT_FLAG1     0x00400000	/* 1  user-defined flag #1	 */
+#define BOT_FLAG2     0x00800000	/* 2  user-defined flag #2	 */
+#define BOT_FLAG3     0x01000000	/* 3  user-defined flag #3	 */
+#define BOT_FLAG4     0x02000000	/* 4  user-defined flag #4	 */
+#define BOT_FLAG5     0x04000000	/* 5  user-defined flag #5	 */
+#define BOT_FLAG6     0x08000000	/* 6  user-defined flag #6	 */
+#define BOT_FLAG7     0x10000000	/* 7  user-defined flag #7	 */
+#define BOT_FLAG8     0x20000000	/* 8  user-defined flag #8	 */
+#define BOT_FLAG9     0x40000000	/* 9  user-defined flag #9	 */
 
 #define BOT_SHARE    (BOT_AGGRESSIVE|BOT_PASSIVE)
 
-/* flag checking macros */
-#define chan_op(x) ((x).chan & USER_OP)
-#define glob_op(x) ((x).global & USER_OP)
-#define chan_deop(x) ((x).chan & USER_DEOP)
-#define glob_deop(x) ((x).global & USER_DEOP)
-#define glob_master(x) ((x).global & USER_MASTER)
-#define glob_bot(x) ((x).global & USER_BOT)
-#define glob_owner(x) ((x).global & USER_OWNER)
-#define chan_master(x) ((x).chan & USER_MASTER)
-#define chan_owner(x) ((x).chan & USER_OWNER)
-#define chan_autoop(x) ((x).chan & USER_AUTOOP)
-#define glob_autoop(x) ((x).global & USER_AUTOOP)
-#define chan_gvoice(x) ((x).chan & USER_GVOICE)
-#define glob_gvoice(x) ((x).global & USER_GVOICE)
-#define chan_kick(x) ((x).chan & USER_KICK)
-#define glob_kick(x) ((x).global & USER_KICK)
-#define chan_voice(x) ((x).chan & USER_VOICE)
-#define glob_voice(x) ((x).global & USER_VOICE)
-#define chan_wasoptest(x) ((x).chan & USER_WASOPTEST)
-#define glob_wasoptest(x) ((x).global & USER_WASOPTEST)
-#define chan_quiet(x) ((x).chan & USER_QUIET)
-#define glob_quiet(x) ((x).global & USER_QUIET)
-#define chan_friend(x) ((x).chan & USER_FRIEND)
-#define glob_friend(x) ((x).global & USER_FRIEND)
-#define glob_botmast(x) ((x).global & USER_BOTMAST)
-#define glob_party(x) ((x).global & USER_PARTY)
-#define glob_xfer(x) ((x).global & USER_XFER)
-#define glob_hilite(x) ((x).global & USER_HIGHLITE)
-
-#define bot_global(x) ((x).bot & BOT_GLOBAL)
-#define bot_chan(x) ((x).chan & BOT_AGGRESSIVE)
-#define bot_shared(x) ((x).bot & BOT_SHARE)
+
+/* Flag checking macros
+ */
+#define chan_op(x)			((x).chan & USER_OP)
+#define glob_op(x)			((x).global & USER_OP)
+#define chan_halfop(x)			((x).chan & USER_HALFOP)
+#define glob_halfop(x)			((x).global & USER_HALFOP)
+#define chan_deop(x)			((x).chan & USER_DEOP)
+#define glob_deop(x)			((x).global & USER_DEOP)
+#define chan_dehalfop(x)		((x).chan & USER_DEHALFOP)
+#define glob_dehalfop(x)		((x).global & USER_DEHALFOP)
+#define glob_master(x)			((x).global & USER_MASTER)
+#define glob_bot(x)				((x).global & USER_BOT)
+#define glob_owner(x)			((x).global & USER_OWNER)
+#define chan_master(x)			((x).chan & USER_MASTER)
+#define chan_owner(x)			((x).chan & USER_OWNER)
+#define chan_autoop(x)			((x).chan & USER_AUTOOP)
+#define glob_autoop(x)			((x).global & USER_AUTOOP)
+#define chan_autohalfop(x)		((x).chan & USER_AUTOHALFOP)
+#define glob_autohalfop(x)		((x).global & USER_AUTOHALFOP)
+#define chan_gvoice(x)			((x).chan & USER_GVOICE)
+#define glob_gvoice(x)			((x).global & USER_GVOICE)
+#define chan_kick(x)			((x).chan & USER_KICK)
+#define glob_kick(x)			((x).global & USER_KICK)
+#define chan_voice(x)			((x).chan & USER_VOICE)
+#define glob_voice(x)			((x).global & USER_VOICE)
+#define chan_wasoptest(x)		((x).chan & USER_WASOPTEST)
+#define glob_wasoptest(x)		((x).global & USER_WASOPTEST)
+#define chan_washalfoptest(x)	((x).chan & USER_WASHALFOPTEST)
+#define glob_washalfoptest(x)	((x).global & USER_WASHALFOPTEST)
+#define chan_quiet(x)			((x).chan & USER_QUIET)
+#define glob_quiet(x)			((x).global & USER_QUIET)
+#define chan_friend(x)			((x).chan & USER_FRIEND)
+#define glob_friend(x)			((x).global & USER_FRIEND)
+#define glob_botmast(x)			((x).global & USER_BOTMAST)
+#define glob_party(x)			((x).global & USER_PARTY)
+#define glob_xfer(x)			((x).global & USER_XFER)
+#define glob_hilite(x) 			((x).global & USER_HIGHLITE)
+#define chan_exempt(x)			((x).chan & USER_EXEMPT)
+#define glob_exempt(x)			((x).global & USER_EXEMPT)
+
+#define bot_global(x)		((x).bot & BOT_GLOBAL)
+#define bot_chan(x)		((x).chan & BOT_AGGRESSIVE)
+#define bot_shared(x)		((x).bot & BOT_SHARE)
+
 
 #ifndef MAKING_MODS
-void get_user_flagrec(struct userrec *, struct flag_record *, char *);
-void set_user_flagrec(struct userrec *, struct flag_record *, char *);
-void break_down_flags(char *, struct flag_record *, struct flag_record *);
+
+void get_user_flagrec(struct userrec *, struct flag_record *, const char *);
+void set_user_flagrec(struct userrec *, struct flag_record *, const char *);
+void break_down_flags(const char *, struct flag_record *, struct flag_record *);
 int build_flags(char *, struct flag_record *, struct flag_record *);
 int flagrec_eq(struct flag_record *, struct flag_record *);
 int flagrec_ok(struct flag_record *, struct flag_record *);

+ 404 - 489
src/lang.h

@@ -1,23 +1,23 @@
-/* 
+/*
  * lang.h
  *   Conversion definitions for language support
- * 
- * $Id: lang.h,v 1.9 2000/01/08 21:23:14 per Exp $
+ *
+ * $Id: lang.h,v 1.27 2002/03/22 04:06:25 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -26,220 +26,164 @@
 #ifndef _EGG_LANG_H
 #define _EGG_LANG_H
 
-#define USAGE            get_language(0x001)
-#define FAILED           get_language(0x002)
+#define MISC_USAGE		get_language(0x001)
+#define MISC_FAILED		get_language(0x002)
 
-/* file area */
-#define FILES_CONVERT    get_language(0x300)
-#define FILES_NOUPDATE   get_language(0x301)
-#define FILES_NOCONVERT  get_language(0x302)
-#define FILES_LSHEAD1    get_language(0x303)
-#define FILES_LSHEAD2    get_language(0x304)
-#define FILES_NOFILES    get_language(0x305)
-#define FILES_NOMATCH    get_language(0x306)
-#define FILES_DIRDNE     get_language(0x307)
-#define FILES_FILEDNE    get_language(0x308)
-#define FILES_NOSHARE    get_language(0x309)
-#define FILES_REMOTE     get_language(0x30a)
-#define FILES_SENDERR    get_language(0x30b)
-#define FILES_SENDING    get_language(0x30c)
-#define FILES_REMOTEREQ  get_language(0x30d)
-#define FILES_BROKEN     get_language(0x30e)
-#define FILES_INVPATH    get_language(0x30f)
-#define FILES_CURDIR     get_language(0x310)
-#define FILES_NEWCURDIR  get_language(0x311)
-#define FILES_NOSUCHDIR  get_language(0x312)
-#define FILES_ILLDIR     get_language(0x313)
-#define FILES_BADNICK    get_language(0x314)
-#define FILES_NOTAVAIL   get_language(0x315)
-#define FILES_REQUESTED  get_language(0x316)
-#define FILES_NORMAL     get_language(0x317)
-#define FILES_CHGLINK    get_language(0x318)
-#define FILES_NOTOWNER   get_language(0x319)
-#define FILES_CREADIR    get_language(0x31a)
-#define FILES_REQACCESS  get_language(0x31b)
-#define FILES_CHGACCESS  get_language(0x31c)
-#define FILES_CHGNACCESS get_language(0x31d)
-#define FILES_REMDIR     get_language(0x31e)
-#define FILES_ILLSOURCE  get_language(0x31f)
-#define FILES_ILLDEST    get_language(0x320)
-#define FILES_STUPID     get_language(0x321)
-#define FILES_EXISTDIR   get_language(0x322)
-#define FILES_SKIPSTUPID get_language(0x323)
-#define FILES_DEST       get_language(0x324)
-#define FILES_COPY       get_language(0x325)
-#define FILES_COPIED     get_language(0x326)
-#define FILES_MOVE       get_language(0x327)
-#define FILES_MOVED      get_language(0x328)
-#define FILES_CANTWRITE  get_language(0x329)
-#define FILES_REQUIRES   get_language(0x32a)
-#define FILES_HID        get_language(0x32b)
-#define FILES_UNHID      get_language(0x32c)
-#define FILES_SHARED     get_language(0x32d)
-#define FILES_UNSHARED   get_language(0x32e)
-#define FILES_ADDLINK    get_language(0x32f)
-#define FILES_CHANGED    get_language(0x330)
-#define FILES_BLANKED    get_language(0x331)
-#define FILES_ERASED     get_language(0x332)
-#define FILES_WELCOME    get_language(0x33a)
-#define FILES_WELCOME1   get_language(0x33b)
-
-/* Userfile messages */
-#define USERF_XFERDONE	get_language(0x400)
-#define USERF_BADREREAD	get_language(0x401)
-#define USERF_CANTREAD	get_language(0x402)
-#define USERF_CANTSEND	get_language(0x403)
-#define USERF_NOMATCH	get_language(0x404)
-#define USERF_OLDFMT	get_language(0x405)
-#define USERF_INVALID	get_language(0x406)
-#define USERF_CORRUPT	get_language(0x407)
-#define USERF_DUPE	get_language(0x408)
-#define USERF_BROKEPASS	get_language(0x409)
-#define USERF_IGNBANS	get_language(0x40a)
-#define USERF_WRITING	get_language(0x40b)
-#define USERF_ERRWRITE	get_language(0x40c)
-#define USERF_ERRWRITE2	get_language(0x40d)
-#define USERF_NONEEDNEW	get_language(0x40e)
-#define USERF_REHASHING	get_language(0x40f)
-#define USERF_UNKNOWN	get_language(0x410)
-#define USERF_NOUSERREC	get_language(0x411)
-#define USERF_BACKUP	get_language(0x412)
-#define USERF_FAILEDXFER get_language(0x413)
-#define USERF_OLDSHARE	get_language(0x414)
-#define USERF_ANTIQUESHARE get_language(0x415)
-#define USERF_REJECTED	get_language(0x416)
+/* Userfile messages
+ */
+#define USERF_XFERDONE		get_language(0x400)
+/* was: USERF_BADREREAD - 0x401 */
+#define USERF_CANTREAD		get_language(0x402)
+#define USERF_CANTSEND		get_language(0x403)
+#define USERF_NOMATCH		get_language(0x404)
+#define USERF_OLDFMT		get_language(0x405)
+#define USERF_INVALID		get_language(0x406)
+#define USERF_CORRUPT		get_language(0x407)
+#define USERF_DUPE		get_language(0x408)
+#define USERF_BROKEPASS		get_language(0x409)
+#define USERF_IGNBANS		get_language(0x40a)
+#define USERF_WRITING		get_language(0x40b)
+#define USERF_ERRWRITE		get_language(0x40c)
+#define USERF_ERRWRITE2		get_language(0x40d)
+#define USERF_NONEEDNEW		get_language(0x40e)
+#define USERF_REHASHING		get_language(0x40f)
+#define USERF_UNKNOWN		get_language(0x410)
+#define USERF_NOUSERREC		get_language(0x411)
+#define USERF_BACKUP		get_language(0x412)
+#define USERF_FAILEDXFER	get_language(0x413)
+#define USERF_OLDSHARE		get_language(0x414)
+#define USERF_ANTIQUESHARE	get_language(0x415)
+#define USERF_REJECTED		get_language(0x416)
 
-/* Misc messages */
-#define MISC_EXPIRED	get_language(0x500)
-#define MISC_TOTAL	get_language(0x501)
-#define MISC_ERASED	get_language(0x502)
-#define MISC_LEFT	get_language(0x503)
-#define MISC_ONLOCALE	get_language(0x504)
-#define MISC_MATCHING	get_language(0x505)
-#define MISC_SKIPPING 	get_language(0x506)
-#define MISC_TRUNCATED	get_language(0x507)
-#define MISC_FOUNDMATCH	get_language(0x508)
-#define MISC_AMBIGUOUS	get_language(0x509)
-#define MISC_NOSUCHCMD	get_language(0x50a)
-#define MISC_CMDBINDS	get_language(0x50b)
-#define MISC_RESTARTING	get_language(0x50c)
-#define MISC_NOMODULES	get_language(0x50d)
-#define MISC_LOGSWITCH	get_language(0x50e)
-#define MISC_OWNER	get_language(0x50f)
-#define MISC_MASTER	get_language(0x510)
-#define MISC_OP		get_language(0x511)
-#define MISC_IDLE	get_language(0x512)
-#define MISC_AWAY	get_language(0x513)
-#define MISC_IGNORING	get_language(0x514)
-#define MISC_UNLINKED	get_language(0x515)
-#define MISC_DISCONNECTED get_language(0x516)
-#define MISC_INVALIDBOT get_language(0x517)
-#define MISC_LOOP	get_language(0x518)
-#define MISC_MUTUAL	get_language(0x519)
-#define MISC_FROM	get_language(0x51a)
-#define MISC_OUTDATED   get_language(0x51b)
-#define MISC_REJECTED	get_language(0x51c)
-#define MISC_IMPOSTER	get_language(0x51d)
-#define MISC_TRYING	get_language(0x51e)
-#define MISC_MOTDFILE	get_language(0x51f)
-#define MISC_NOMOTDFILE get_language(0x520)
-#define MISC_USEFORMAT	get_language(0x521)
-#define MISC_CHADDRFORMAT get_language(0x522)
-#define MISC_UNKNOWN	get_language(0x523)
-#define MISC_CHANNELS	get_language(0x524)
-#define MISC_TRYINGMISTAKE	get_language(0x525)
-#define MISC_PENDING	get_language(0x526)
-#define MISC_WANTOPS	get_language(0x527)
-#define MISC_LURKING	get_language(0x528)
-#define MISC_BACKGROUND	get_language(0x529)
-#define MISC_TERMMODE	get_language(0x52a)
-#define MISC_STATMODE	get_language(0x52b)
-#define MISC_LOGMODE	get_language(0x52c)
-#define MISC_ONLINEFOR	get_language(0x52d)
-#define MISC_CACHEHIT	get_language(0x52e)
-#define MISC_TCLLIBVER	get_language(0x52f)
-#define MISC_NEWUSERFLAGS get_language(0x530)
-#define MISC_NOTIFY	get_language(0x531)
-#define MISC_PERMOWNER	get_language(0x532)
-#define MISC_ROOTWARN	get_language(0x533)
-#define MISC_NOCONFIGFILE get_language(0x534)
-#define MISC_NOUSERFILE	get_language(0x535)
-#define MISC_USERFCREATE get_language(0x536)
-#define MISC_USERFCREATE1 get_language(0x537)
-#define MISC_USERFCREATE2 get_language(0x538)
-#define MISC_USERFEXISTS get_language(0x539)
-#define MISC_CANTWRITETEMP get_language(0x53a)
-#define MISC_CANTRELOADUSER get_language(0x53b)
-#define MISC_MISSINGUSERF get_language(0x53c)
-#define MISC_BOTSCONNECTED get_language(0x53d)
-#define MISC_BANNER     get_language(0x53e)
-#define MISC_CLOGS      get_language(0x53f)
-#define MISC_BANNER_STEALTH get_language(0x540)
-#define MISC_LOGREPEAT  get_language(0x541)
-#define MISC_NOUSERFILE2 get_language(0x542)
+/* Misc messages
+ */
+#define MISC_EXPIRED		get_language(0x500)
+#define MISC_TOTAL		get_language(0x501)
+#define MISC_ERASED		get_language(0x502)
+/* was: MISC_LEFT - 0x503 */
+#define MISC_ONLOCALE		get_language(0x504)
+#define MISC_MATCHING		get_language(0x505)
+#define MISC_SKIPPING		get_language(0x506)
+#define MISC_TRUNCATED		get_language(0x507)
+#define MISC_FOUNDMATCH		get_language(0x508)
+#define MISC_AMBIGUOUS		get_language(0x509)
+#define MISC_NOSUCHCMD		get_language(0x50a)
+#define MISC_CMDBINDS		get_language(0x50b)
+#define MISC_RESTARTING		get_language(0x50c)
+#define MISC_MATCH_PLURAL	get_language(0x50d)
+#define MISC_LOGSWITCH		get_language(0x50e)
+#define MISC_OWNER		get_language(0x50f)
+#define MISC_MASTER		get_language(0x510)
+#define MISC_OP			get_language(0x511)
+#define MISC_IDLE		get_language(0x512)
+#define MISC_AWAY		get_language(0x513)
+/* was: MISC_IGNORING - 0x514 */
+/* was: MISC_UNLINKED - 0x515 */
+#define MISC_DISCONNECTED	get_language(0x516)
+#define MISC_INVALIDBOT		get_language(0x517)
+#define MISC_LOOP		get_language(0x518)
+/* was: MISC_MUTUAL - 0x519 */
+#define MISC_FROM		get_language(0x51a)
+#define MISC_OUTDATED		get_language(0x51b)
+#define MISC_REJECTED		get_language(0x51c)
+#define MISC_IMPOSTER		get_language(0x51d)
+#define MISC_TRYING		get_language(0x51e)
+#define MISC_MOTDFILE		get_language(0x51f)
+#define MISC_NOMOTDFILE		get_language(0x520)
+#define MISC_USEFORMAT		get_language(0x521)
+#define MISC_CHADDRFORMAT	get_language(0x522)
+/* was: MISC_UNKNOWN - 0x523 */
+/* was: MISC_CHANNELS - 0x524 */
+/* was: MISC_TRYINGMISTAKE - 0x525 */
+#define MISC_PENDING		get_language(0x526)
+#define MISC_WANTOPS		get_language(0x527)
+#define MISC_LURKING		get_language(0x528)
+#define MISC_BACKGROUND		get_language(0x529)
+#define MISC_TERMMODE		get_language(0x52a)
+#define MISC_STATMODE		get_language(0x52b)
+#define MISC_LOGMODE		get_language(0x52c)
+#define MISC_ONLINEFOR		get_language(0x52d)
+#define MISC_CACHEHIT		get_language(0x52e)
+#define MISC_TCLLIBRARY		get_language(0x52f)
+#define MISC_NEWUSERFLAGS	get_language(0x530)
+#define MISC_NOTIFY		get_language(0x531)
+#define MISC_PERMOWNER		get_language(0x532)
+/* was: MISC_ROOTWARN - 0x533 */
+#define MISC_NOCONFIGFILE	get_language(0x534)
+#define MISC_NOUSERFILE		get_language(0x535)
+#define MISC_NOUSERFILE2	get_language(0x536)
+#define MISC_USERFCREATE1	get_language(0x537)
+#define MISC_USERFCREATE2	get_language(0x538)
+#define MISC_USERFEXISTS	get_language(0x539)
+#define MISC_CANTWRITETEMP	get_language(0x53a)
+#define MISC_CANTRELOADUSER	get_language(0x53b)
+#define MISC_MISSINGUSERF	get_language(0x53c)
+/* was: MISC_BOTSCONNECTED - 0x53d */
+#define MISC_BANNER		get_language(0x53e)
+#define MISC_CLOGS		get_language(0x53f)
+#define MISC_BANNER_STEALTH	get_language(0x540)
+#define MISC_LOGREPEAT		get_language(0x541)
+#define MISC_JUPED		get_language(0x542)
+#define MISC_NOFREESOCK		get_language(0x543)
+#define MISC_TCLVERSION		get_language(0x544)
+#define MISC_TCLHVERSION	get_language(0x545)
 
 /* IRC */
-#define IRC_BANNED	get_language(0x600)
-#define IRC_YOUREBANNED	get_language(0x601)
+#define IRC_BANNED		get_language(0x600)
+#define IRC_YOUREBANNED		get_language(0x601)
 /* BOT log messages when attempting to place a ban which matches me */
-#define IRC_IBANNEDME	get_language(0x602)
-#define IRC_FUNKICK	get_language(0x603)
-#define IRC_HI		get_language(0x604)
-#define IRC_GOODBYE	get_language(0x605)
-#define IRC_BANNED2	get_language(0x606)
-#define IRC_NICKTOOLONG get_language(0x607)
-#define IRC_INTRODUCED	get_language(0x608)
-#define IRC_COMMONSITE	get_language(0x609)
-#define IRC_SALUT1	get_language(0x60a)
-#define IRC_SALUT1_ARGS	nick, nick, botname
-#define IRC_SALUT2	get_language(0x60b)
-#define IRC_SALUT2_ARGS	nick, host
-#define IRC_SALUT2A	get_language(0x60c)
-#define IRC_SALUT2B	get_language(0x60d)
-#define IRC_INITOWNER1	get_language(0x60e)
-#define IRC_INIT1	get_language(0x60f)
-#define IRC_INIT1_ARGS	nick
-#define IRC_INITNOTE	get_language(0x610)
-#define IRC_INITINTRO	get_language(0x611)
-#define IRC_PASS	get_language(0x612)
-#define IRC_NOPASS	get_language(0x613)
-#define IRC_NOPASS2	get_language(0x614)
-#define IRC_EXISTPASS	get_language(0x615)
-#define IRC_PASSFORMAT	get_language(0x616)
-#define IRC_SETPASS	get_language(0x617)
-#define IRC_FAILPASS	get_language(0x618)
-#define IRC_CHANGEPASS	get_language(0x619)
-#define IRC_FAILCOMMON	get_language(0x61a)
-#define IRC_MISIDENT	get_language(0x61b)
-#define IRC_MISIDENT_ARGS	nick, nick, u->handle
-#define IRC_MISIDENT_ARGS2	nick, who, u->handle
-#define IRC_DENYACCESS	get_language(0x61c)
-#define IRC_RECOGNIZED	get_language(0x61d)
-#define IRC_ADDHOSTMASK	get_language(0x61e)
-#define IRC_DELMAILADDR	get_language(0x61f)
+#define IRC_IBANNEDME		get_language(0x602)
+#define IRC_FUNKICK		get_language(0x603)
+#define IRC_HI			get_language(0x604)
+#define IRC_GOODBYE		get_language(0x605)
+#define IRC_BANNED2		get_language(0x606)
+#define IRC_NICKTOOLONG		get_language(0x607)
+#define IRC_INTRODUCED		get_language(0x608)
+#define IRC_COMMONSITE		get_language(0x609)
+#define IRC_SALUT1		get_language(0x60a)
+#define IRC_SALUT2		get_language(0x60b)
+#define IRC_SALUT2A		get_language(0x60c)
+#define IRC_SALUT2B		get_language(0x60d)
+#define IRC_INITOWNER1		get_language(0x60e)
+#define IRC_INIT1		get_language(0x60f)
+#define IRC_INITNOTE		get_language(0x610)
+#define IRC_INITINTRO		get_language(0x611)
+#define IRC_PASS		get_language(0x612)
+#define IRC_NOPASS		get_language(0x613)
+/* was: IRC_NOPASS2 - 0x614 */
+#define IRC_EXISTPASS		get_language(0x615)
+#define IRC_PASSFORMAT		get_language(0x616)
+#define IRC_SETPASS		get_language(0x617)
+#define IRC_FAILPASS		get_language(0x618)
+#define IRC_CHANGEPASS		get_language(0x619)
+#define IRC_FAILCOMMON		get_language(0x61a)
+#define IRC_MISIDENT		get_language(0x61b)
+#define IRC_DENYACCESS		get_language(0x61c)
+#define IRC_RECOGNIZED		get_language(0x61d)
+#define IRC_ADDHOSTMASK		get_language(0x61e)
+/* was: IRC_DELMAILADDR - 0x61f */
 #define IRC_FIELDCURRENT	get_language(0x620)
 #define IRC_FIELDCHANGED	get_language(0x621)
 #define IRC_FIELDTOREMOVE	get_language(0x622)
-#define IRC_NOEMAIL	get_language(0x623)
-#define IRC_INFOLOCKED	get_language(0x624)
-#define IRC_REMINFOON	get_language(0x625)
-#define IRC_REMINFO	get_language(0x626)
-#define IRC_NOINFOON	get_language(0x627)
-#define IRC_NOINFO	get_language(0x628)
-#define IRC_NOMONITOR	get_language(0x629)
-#define IRC_RESETCHAN	get_language(0x62a)
-#define IRC_JUMP	get_language(0x62b)
-#define IRC_CHANHIDDEN	get_language(0x62c)
-#define IRC_ONCHANNOW	get_language(0x62d)
-#define IRC_NEVERJOINED	get_language(0x62e)
-#define IRC_LASTSEENAT	get_language(0x62f)
-#define IRC_DONTKNOWYOU	get_language(0x630)
-#define IRC_NOHELP	get_language(0x631)
-#define IRC_NOHELP2	get_language(0x632)
-#define IRC_NOTNORMFILE	get_language(0x633)
-#define IRC_NOTONCHAN	get_language(0x634)
-#define IRC_GETORIGNICK	get_language(0x635)
-#define IRC_BADBOTNICK	get_language(0x636)
+/* was: IRC_NOEMAIL - 0x623 */
+#define IRC_INFOLOCKED		get_language(0x624)
+#define IRC_REMINFOON		get_language(0x625)
+#define IRC_REMINFO		get_language(0x626)
+#define IRC_NOINFOON		get_language(0x627)
+#define IRC_NOINFO		get_language(0x628)
+#define IRC_NOMONITOR		get_language(0x629)
+#define IRC_RESETCHAN		get_language(0x62a)
+#define IRC_JUMP		get_language(0x62b)
+#define IRC_CHANHIDDEN		get_language(0x62c)
+#define IRC_ONCHANNOW		get_language(0x62d)
+#define IRC_NEVERJOINED		get_language(0x62e)
+#define IRC_LASTSEENAT		get_language(0x62f)
+#define IRC_DONTKNOWYOU		get_language(0x630)
+#define IRC_NOHELP		get_language(0x631)
+#define IRC_NOHELP2		get_language(0x632)
+#define IRC_NOTONCHAN		get_language(0x634)
+#define IRC_GETORIGNICK		get_language(0x635)
+#define IRC_BADBOTNICK		get_language(0x636)
 #define IRC_BOTNICKINUSE	get_language(0x637)
 #define IRC_CANTCHANGENICK	get_language(0x638)
 #define IRC_BOTNICKJUPED	get_language(0x639)
@@ -247,7 +191,7 @@
 #define IRC_NOTREGISTERED1	get_language(0x63b)
 #define	IRC_NOTREGISTERED2	get_language(0x63c)
 #define IRC_FLOODIGNORE1	get_language(0x63d)
-#define IRC_FLOODIGNORE2	get_language(0x63e)
+/* was: IRC_FLOODIGNORE2 - 0x63e */
 #define IRC_FLOODIGNORE3	get_language(0x63f)
 #define IRC_FLOODKICK		get_language(0x640)
 #define IRC_SERVERTRY		get_language(0x641)
@@ -259,7 +203,7 @@
 #define IRC_MODEQUEUE		get_language(0x647)
 #define IRC_SERVERQUEUE		get_language(0x648)
 #define IRC_HELPQUEUE		get_language(0x649)
-#define IRC_BOTNOTONIRC		get_language(0x64a)
+/* was: IRC_BOTNOTONIRC - 0x64a */
 #define IRC_NOTACTIVECHAN	get_language(0x64b)
 #define IRC_PROCESSINGCHAN	get_language(0x64c)
 #define IRC_CHANNEL		get_language(0x64d)
@@ -282,314 +226,285 @@
 #define IRC_BANNEDFROMCHAN	get_language(0x65e)
 #define IRC_SERVNOTONCHAN	get_language(0x65f)
 #define IRC_BADCHANKEY		get_language(0x660)
-#define IRC_INTRO1              get_language(0x661)
-#define IRC_INTRO1_ARGS nick, botname
-#define IRC_BADHOST1            get_language(0x662)
-#define IRC_BADHOST1_ARGS nick
-#define IRC_BADHOST2            get_language(0x663)
-#define IRC_BADHOST2_ARGS nick, botname
-#define IRC_NEWBOT1             get_language(0x664)
-#define IRC_NEWBOT1_ARGS nick, botname
-#define IRC_NEWBOT2             get_language(0x665)
-#define IRC_NEWBOT2_ARGS nick
-#define IRC_TELNET              get_language(0x666)
-#define IRC_TELNET_ARGS botnetnick
-#define IRC_TELNET1             get_language(0x667)
-#define IRC_LIMBO               get_language(0x668)
-#define IRC_TELNETFLOOD         get_language(0x669)
-#define IRC_PREBANNED           get_language(0x66a)
-#define IRC_LEMMINGBOT          get_language(0x66b)
-#define IRC_KICK_PROTECT        get_language(0x66c)
-#define IRC_DEOP_PROTECT        get_language(0x66f)
-#define IRC_COMMENTKICK         get_language(0x66d)
-#define IRC_GETALTNICK	get_language(0x66e)
-#define IRC_REMOVEDEXEMPT       get_language(0x670)
-#define IRC_REMOVEDINVITE       get_language(0x671)
-#define IRC_FLOODIGNORE4        get_language(0x672)
+#define IRC_INTRO1		get_language(0x661)
+#define IRC_BADHOST1		get_language(0x662)
+#define IRC_BADHOST2		get_language(0x663)
+#define IRC_NEWBOT1		get_language(0x664)
+#define IRC_NEWBOT2		get_language(0x665)
+#define IRC_TELNET		get_language(0x666)
+#define IRC_TELNET1		get_language(0x667)
+#define IRC_LIMBO		get_language(0x668)
+#define IRC_TELNETFLOOD		get_language(0x669)
+#define IRC_PREBANNED		get_language(0x66a)
+#define IRC_JOIN_FLOOD		get_language(0x66b)
+#define IRC_KICK_PROTECT	get_language(0x66c)
+#define IRC_DEOP_PROTECT	get_language(0x66f)
+#define IRC_COMMENTKICK		get_language(0x66d)
+#define IRC_GETALTNICK		get_language(0x66e)
+#define IRC_REMOVEDEXEMPT	get_language(0x670)
+#define IRC_REMOVEDINVITE	get_language(0x671)
+#define IRC_FLOODIGNORE4	get_language(0x672)
+#define IRC_NICK_FLOOD		get_language(0x673)
 
-/* Eggdrop command line usage */
-#define EGG_USAGE	get_language(0x700)
-#define EGG_RUNNING1	get_language(0x701)
-#define EGG_RUNNING2	get_language(0x702)
-#define EGG_NOWRITE     get_language(0x703)
+/* Eggdrop command line usage
+ */
+#define EGG_USAGE		get_language(0x700)
+#define EGG_RUNNING1		get_language(0x701)
+#define EGG_RUNNING2		get_language(0x702)
+#define EGG_NOWRITE		get_language(0x703)
 
-#define USER_ISGLOBALOP	get_language(0x800)
-#define USER_ISBOT	get_language(0x801)
-#define USER_ISMASTER	get_language(0x802)
+#define USER_ISGLOBALOP		get_language(0x800)
+#define USER_ISBOT		get_language(0x801)
+#define USER_ISMASTER		get_language(0x802)
 
-/* '.bans/.invites/.exempts' common messages */
+/* '.bans/.invites/.exempts' common messages
+ */
 #define MODES_CREATED		get_language(0x130)
 #define MODES_LASTUSED		get_language(0x131)
 #define MODES_INACTIVE		get_language(0x132)
 #define MODES_PLACEDBY		get_language(0x133)
 #define MODES_NOTACTIVE		get_language(0x135)
-#define MODES_NOTACTIVE2 	get_language(0x137)
+#define MODES_NOTACTIVE2	get_language(0x137)
 #define MODES_NOTBYBOT		get_language(0x138)
 
-/* Messages used when listing with `.bans' */
-#define BANS_GLOBAL	get_language(0x104)
-#define BANS_BYCHANNEL	get_language(0x106)
-#define BANS_USEBANSALL	get_language(0x109)
-#define BANS_NOLONGER	get_language(0x10a)
+/* Messages used when listing with `.bans'
+ */
+#define BANS_GLOBAL		get_language(0x104)
+#define BANS_BYCHANNEL		get_language(0x106)
+#define BANS_USEBANSALL		get_language(0x109)
+#define BANS_NOLONGER		get_language(0x10a)
 
-/* Messages used when listing with '.exempts' */
-#define EXEMPTS_GLOBAL	        get_language(0x114)
+/* Messages used when listing with '.exempts'
+ */
+#define EXEMPTS_GLOBAL		get_language(0x114)
 #define EXEMPTS_BYCHANNEL	get_language(0x116)
 #define EXEMPTS_USEEXEMPTSALL	get_language(0x119)
 #define EXEMPTS_NOLONGER	get_language(0x11a)
 
-/* Messages used when listing with '.invites' */
-#define INVITES_GLOBAL	        get_language(0x124)
+/* Messages used when listing with '.invites'
+ */
+#define INVITES_GLOBAL		get_language(0x124)
 #define INVITES_BYCHANNEL	get_language(0x126)
 #define INVITES_USEINVITESALL	get_language(0x129)
 #define INVITES_NOLONGER	get_language(0x12a)
 
 
-/* Messages referring to channels */
-#define CHAN_NOSUCH	get_language(0x900)
-#define CHAN_BADCHANKEY	get_language(0x901)
+/* Messages referring to channels
+ */
+#define CHAN_NOSUCH		get_language(0x900)
 #define CHAN_BADCHANMODE	get_language(0x902)
-#define CHAN_BADCHANMODE_ARGS	chan->name, who
-#define CHAN_BADCHANMODE_ARGS2	chan->name, op
-#define CHAN_MASSDEOP	get_language(0x903)
-#define CHAN_MASSDEOP_ARGS	chan->name, from
+#define CHAN_MASSDEOP		get_language(0x903)
 #define CHAN_MASSDEOP_KICK	get_language(0x904)
-#define CHAN_BADBAN	get_language(0x905)
-#define CHAN_PERMBANNED	get_language(0x906)
-#define CHAN_FORCEJOIN	get_language(0x907)
-#define CHAN_FAKEMODE	get_language(0x908)
+#define CHAN_FORCEJOIN		get_language(0x907)
+#define CHAN_FAKEMODE		get_language(0x908)
 #define CHAN_FAKEMODE_KICK	get_language(0x909)
-#define CHAN_DESYNCMODE	get_language(0x90a)
+#define CHAN_DESYNCMODE		get_language(0x90a)
 #define CHAN_DESYNCMODE_KICK	get_language(0x90b)
-#define CHAN_FLOOD get_language(0x90c)
-#define CHAN_BOGUSBAN	get_language(0x90d)
-#define CHAN_BOGUSUSERNAME	get_language(0x90e)
-#define CHAN_BOGUSEXEMPT	get_language(0x90f)
-#define CHAN_BOGUSINVITE	get_language(0x910)
+#define CHAN_FLOOD		get_language(0x90c)
 
-/* Messages referring to ignores */
-#define IGN_NONE	get_language(0xa00)
-#define IGN_CURRENT	get_language(0xa01)
-#define IGN_NOLONGER	get_language(0xa02)
+/* Messages referring to ignores
+ */
+#define IGN_NONE		get_language(0xa00)
+#define IGN_CURRENT		get_language(0xa01)
+#define IGN_NOLONGER		get_language(0xa02)
 
-/* Messages referring to bots */
-#define BOT_NOTHERE	get_language(0xb00)
-#define BOT_NONOTES	get_language(0xb01)
-#define BOT_USERAWAY	get_language(0xb02)
-#define BOT_NOTEUNSUPP	get_language(0xb03)
-#define BOT_NOTES2MANY	get_language(0xb04)
-#define BOT_NOTESERROR1	get_language(0xb05)
-#define BOT_NOTESERROR2	get_language(0xb06)
-#define BOT_NOTEARRIVED	get_language(0xb07)
-#define BOT_NOTESTORED	get_language(0xb08)
-#define BOT_NOTEDELIV	get_language(0xb09)
-#define BOT_NOTEOUTSIDE	get_language(0xb0a)
-#define BOT_NOTESUSAGE	get_language(0xb0b)
-#define BOT_NOMESSAGES	get_language(0xb0c)
-#define BOT_NOTEEXP1	get_language(0xb0d)
-#define BOT_NOTEEXP2	get_language(0xb0e)
-#define BOT_NOTEWAIT	get_language(0xb0f)
-#define BOT_NOTTHATMANY	get_language(0xb10)
-#define BOT_NOTEUSAGE	get_language(0xb11)
-#define BOT_CANTMODNOTE	get_language(0xb12)
-#define BOT_NOTESERASED	get_language(0xb13)
-#define BOT_NOTESWAIT1	get_language(0xb14)
-#define BOT_NOTESWAIT1_ARGS	m->nick, k, k == 1 ? "" : "s", origbotname
-#define BOT_NOTESWAIT1_ARGS2	nick, k, k == 1 ? "" : "s", origbotname
-#define BOT_NOTESWAIT2	get_language(0xb15)
-#define BOT_NOTESWAIT3	get_language(0xb16)
-#define BOT_NOTESWAIT3_ARGS k, k == 1 ? "" : "s"
-#define BOT_NOTESWAIT4	get_language(0xb17)
-#define BOT_MSGDIE	get_language(0xb18)
-#define BOT_NOSUCHUSER  get_language(0xb19)
-#define BOT_NOCHANNELS  get_language(0xb1a)
-#define BOT_PARTYMEMBS  get_language(0xb1b)
-#define BOT_BOTSCONNECTED get_language(0xb1c)
-#define BOT_OTHERPEOPLE	get_language(0xb1d)
-#define BOT_OUTDATEDWHOM get_language(0xb1e)
-#define BOT_LINKATTEMPT get_language(0xb1f)
-#define BOT_NOTESTORED2	get_language(0xb20)
-#define BOT_NOTEBOXFULL get_language(0xb21)
-#define BOT_NOTEISAWAY  get_language(0xb22)
-#define BOT_NOTESENTTO  get_language(0xb23)
-#define BOT_DISCONNECTED get_language(0xb24)
-#define BOT_PEOPLEONCHAN get_language(0xb25)
-#define BOT_CANTLINKTHERE get_language(0xb26)
-#define BOT_CANTUNLINK	get_language(0xb27)
-#define BOT_LOOPDETECT get_language(0xb28)
-#define BOT_BOGUSLINK	get_language(0xb29)
-#define BOT_BOGUSLINK2	get_language(0xb2a)
-#define BOT_DISCONNLEAF	get_language(0xb2b)
-#define BOT_LINKEDTO	get_language(0xb2c)
-#define BOT_ILLEGALLINK get_language(0xb2d)
-#define BOT_YOUREALEAF  get_language(0xb2e)
-#define BOT_REJECTING	get_language(0xb2f)
-#define BOT_OLDBOT	get_language(0xb30)
-#define BOT_TRACERESULT	get_language(0xb31)
-#define BOT_DOESNTEXIST	get_language(0xb32)
-#define BOT_NOREMOTEBOOT get_language(0xb33)
-#define BOT_NOOWNERBOOT	get_language(0xb34)
-#define BOT_XFERREJECTED get_language(0xb35)
-#define BOT_NOFILESYS	get_language(0xb36)
-#define BOT_BOTNETUSERS	get_language(0xb37)
-#define BOT_PARTYLINE	get_language(0xb38)
-#define BOT_LOCALCHAN	get_language(0xb39)
-#define BOT_USERSONCHAN	get_language(0xb3a)
-#define BOT_NOBOTSLINKED get_language(0xb3b)
-#define BOT_NOTRACEINFO	get_language(0xb3c)
-#define BOT_COMPLEXTREE	get_language(0xb3d)
-#define BOT_UNLINKALL	get_language(0xb3e)
-#define BOT_KILLLINKATTEMPT get_language(0xb3f)
-#define BOT_ENDLINKATTEMPT get_language(0xb40)
-#define BOT_BREAKLINK	get_language(0xb41)
-#define BOT_UNLINKEDFROM get_language(0xb42)
-#define BOT_NOTCONNECTED get_language(0xb43)
-#define BOT_WIPEBOTTABLE get_language(0xb44)
-#define BOT_BOTUNKNOWN	get_language(0xb45)
-#define BOT_CANTLINKMYSELF get_language(0xb46)
-#define BOT_ALREADYLINKED get_language(0xb47)
-#define BOT_NOTELNETADDY get_language(0xb48)
-#define BOT_LINKING	get_language(0xb49)
-#define BOT_CANTFINDRELAYUSER get_language(0xb4a)
-#define BOT_CANTLINKTO	get_language(0xb4b)
-#define BOT_CANTRELAYMYSELF get_language(0xb4c)
-#define BOT_CONNECTINGTO get_language(0xb4d)
-#define BOT_BYEINFO1	get_language(0xb4e)
-#define BOT_ABORTRELAY1 get_language(0xb4f)
-#define BOT_ABORTRELAY2 get_language(0xb50)
-#define BOT_ABORTRELAY3 get_language(0xb51)
-#define BOT_PARTYJOINED	get_language(0xb52)
-#define BOT_LOSTDCCUSER	get_language(0xb53)
-#define BOT_DROPPINGRELAY get_language(0xb54)
-#define BOT_RELAYSUCCESS get_language(0xb55)
-#define BOT_BYEINFO2	get_language(0xb56)
-#define BOT_RELAYLINK	get_language(0xb57)
-#define BOT_PARTYLEFT	get_language(0xb58)
-#define BOT_ENDRELAY1	get_language(0xb59)
-#define BOT_ENDRELAY2	get_language(0xb5a)
-#define BOT_PARTYREJOINED get_language(0xb5b)
-#define BOT_DROPPEDRELAY get_language(0xb5c)
-#define BOT_BREAKRELAY	get_language(0xb5d)
-#define BOT_RELAYBROKEN	get_language(0xb5e)
-#define BOT_PINGTIMEOUT	get_language(0xb5f)
-#define BOT_BOTNOTLEAFLIKE get_language(0xb60)
-#define BOT_BOTDROPPED	get_language(0xb61)
-#define BOT_ALREADYLINKING get_language(0xb62)
+/* Messages referring to bots
+ */
+#define BOT_NOTHERE		get_language(0xb00)
+#define BOT_NONOTES		get_language(0xb01)
+#define BOT_USERAWAY		get_language(0xb02)
+#define BOT_NOTEARRIVED		get_language(0xb07)
+#define BOT_MSGDIE		get_language(0xb18)
+#define BOT_NOSUCHUSER		get_language(0xb19)
+#define BOT_NOCHANNELS		get_language(0xb1a)
+#define BOT_PARTYMEMBS		get_language(0xb1b)
+#define BOT_BOTSCONNECTED	get_language(0xb1c)
+#define BOT_OTHERPEOPLE		get_language(0xb1d)
+/* was: BOT_OUTDATEDWHOM - 0xb1e */
+#define BOT_LINKATTEMPT		get_language(0xb1f)
+#define BOT_NOTESTORED2		get_language(0xb20)
+#define BOT_NOTEBOXFULL		get_language(0xb21)
+#define BOT_NOTEISAWAY		get_language(0xb22)
+#define BOT_NOTESENTTO		get_language(0xb23)
+#define BOT_DISCONNECTED	get_language(0xb24)
+#define BOT_PEOPLEONCHAN	get_language(0xb25)
+#define BOT_CANTLINKTHERE	get_language(0xb26)
+#define BOT_CANTUNLINK		get_language(0xb27)
+#define BOT_LOOPDETECT		get_language(0xb28)
+#define BOT_BOGUSLINK		get_language(0xb29)
+/* was: BOT_BOGUSLINK2 - 0xb2a */
+#define BOT_DISCONNLEAF		get_language(0xb2b)
+#define BOT_LINKEDTO		get_language(0xb2c)
+#define BOT_ILLEGALLINK		get_language(0xb2d)
+#define BOT_YOUREALEAF		get_language(0xb2e)
+#define BOT_REJECTING		get_language(0xb2f)
+#define BOT_OLDBOT		get_language(0xb30)
+#define BOT_TRACERESULT		get_language(0xb31)
+#define BOT_DOESNTEXIST		get_language(0xb32)
+#define BOT_NOREMOTEBOOT	get_language(0xb33)
+#define BOT_NOOWNERBOOT		get_language(0xb34)
+#define BOT_XFERREJECTED	get_language(0xb35)
+/* was: BOT_NOFILESYS - 0xb36 */
+#define BOT_BOTNETUSERS		get_language(0xb37)
+#define BOT_PARTYLINE		get_language(0xb38)
+#define BOT_LOCALCHAN		get_language(0xb39)
+#define BOT_USERSONCHAN		get_language(0xb3a)
+#define BOT_NOBOTSLINKED	get_language(0xb3b)
+#define BOT_NOTRACEINFO		get_language(0xb3c)
+#define BOT_COMPLEXTREE		get_language(0xb3d)
+#define BOT_UNLINKALL		get_language(0xb3e)
+#define BOT_KILLLINKATTEMPT	get_language(0xb3f)
+#define BOT_ENDLINKATTEMPT	get_language(0xb40)
+#define BOT_BREAKLINK		get_language(0xb41)
+#define BOT_UNLINKEDFROM	get_language(0xb42)
+#define BOT_NOTCONNECTED	get_language(0xb43)
+#define BOT_WIPEBOTTABLE	get_language(0xb44)
+#define BOT_BOTUNKNOWN		get_language(0xb45)
+#define BOT_CANTLINKMYSELF	get_language(0xb46)
+#define BOT_ALREADYLINKED	get_language(0xb47)
+#define BOT_NOTELNETADDY	get_language(0xb48)
+#define BOT_LINKING		get_language(0xb49)
+#define BOT_CANTFINDRELAYUSER	get_language(0xb4a)
+#define BOT_CANTLINKTO		get_language(0xb4b)
+#define BOT_CANTRELAYMYSELF	get_language(0xb4c)
+#define BOT_CONNECTINGTO	get_language(0xb4d)
+#define BOT_BYEINFO1		get_language(0xb4e)
+#define BOT_ABORTRELAY1		get_language(0xb4f)
+#define BOT_ABORTRELAY2		get_language(0xb50)
+#define BOT_ABORTRELAY3		get_language(0xb51)
+/* was: BOT_PARTYJOINED - 0xb52 */
+#define BOT_LOSTDCCUSER		get_language(0xb53)
+#define BOT_DROPPINGRELAY	get_language(0xb54)
+#define BOT_RELAYSUCCESS	get_language(0xb55)
+#define BOT_BYEINFO2		get_language(0xb56)
+#define BOT_RELAYLINK		get_language(0xb57)
+#define BOT_PARTYLEFT		get_language(0xb58)
+#define BOT_ENDRELAY1		get_language(0xb59)
+#define BOT_ENDRELAY2		get_language(0xb5a)
+#define BOT_PARTYREJOINED	get_language(0xb5b)
+#define BOT_DROPPEDRELAY	get_language(0xb5c)
+#define BOT_BREAKRELAY		get_language(0xb5d)
+#define BOT_RELAYBROKEN		get_language(0xb5e)
+#define BOT_PINGTIMEOUT		get_language(0xb5f)
+#define BOT_BOTNOTLEAFLIKE	get_language(0xb60)
+#define BOT_BOTDROPPED		get_language(0xb61)
+#define BOT_ALREADYLINKING	get_language(0xb62)
 
-/* Messages pertaining to MODULES */
-#define MOD_ALREADYLOAD	get_language(0x200)
-#define MOD_BADCWD	get_language(0x201)
-#define MOD_NOSTARTDEF	get_language(0x202)
-#define MOD_LOADED	get_language(0x203)
-#define MOD_NEEDED	get_language(0x204)
-#define MOD_NOCLOSEDEF	get_language(0x205)
-#define MOD_UNLOADED	get_language(0x206)
-#define MOD_NOSUCH	get_language(0x207)
-#define MOD_NOINFO	get_language(0x208)
-#define MOD_LOADERROR	get_language(0x209)
-#define MOD_UNLOADERROR	get_language(0x20a)
-#define MOD_CANTLOADMOD	get_language(0x20b)
-#define MOD_STAGNANT	get_language(0x20c)
-#define MOD_NOCRYPT	get_language(0x20d)
-#define MOD_NOFILESYSMOD get_language(0x20e)
+/* Messages pertaining to MODULES
+ */
+#define MOD_ALREADYLOAD		get_language(0x200)
+#define MOD_BADCWD		get_language(0x201)
+#define MOD_NOSTARTDEF		get_language(0x202)
+#define MOD_NEEDED		get_language(0x204)
+#define MOD_NOCLOSEDEF		get_language(0x205)
+#define MOD_UNLOADED		get_language(0x206)
+#define MOD_NOSUCH		get_language(0x207)
+/* was: MOD_NOINFO - 0x208 */
+#define MOD_LOADERROR		get_language(0x209)
+#define MOD_UNLOADERROR		get_language(0x20a)
+#define MOD_CANTLOADMOD		get_language(0x20b)
+#define MOD_STAGNANT		get_language(0x20c)
+#define MOD_NOCRYPT		get_language(0x20d)
+#define MOD_NOFILESYSMOD	get_language(0x20e)
+#define MOD_LOADED_WITH_LANG	get_language(0x20f)
+#define MOD_LOADED		get_language(0x210)
 
-#define DCC_NOSTRANGERS	get_language(0xc00)
-#define DCC_REFUSED	get_language(0xc01)
-#define DCC_REFUSED2	get_language(0xc02)
-#define DCC_REFUSED3	get_language(0xc03)
-#define DCC_REFUSED4	get_language(0xc04)
-#define DCC_REFUSED5	get_language(0xc05)
-#define DCC_REFUSED6	get_language(0xc06)
-#define DCC_REFUSED7    get_language(0xc21)
-#define DCC_TOOMANY	get_language(0xc07)
-#define DCC_TRYLATER	get_language(0xc08)
-#define DCC_REFUSEDTAND	get_language(0xc09)
-#define DCC_NOSTRANGERFILES1	get_language(0xc0a)
-#define DCC_NOSTRANGERFILES2	get_language(0xc0b)
+#define DCC_NOSTRANGERS		get_language(0xc00)
+#define DCC_REFUSED		get_language(0xc01)
+#define DCC_REFUSED2		get_language(0xc02)
+#define DCC_REFUSED3		get_language(0xc03)
+#define DCC_REFUSED4		get_language(0xc04)
+#define DCC_REFUSED5		get_language(0xc05)
+/* was: DCC_REFUSED6 - 0xc06 */
+#define DCC_REFUSED7		get_language(0xc21)
+#define DCC_TOOMANY		get_language(0xc07)
+/* was: DCC_TRYLATER - 0xc08 */
+/* was: DCC_REFUSEDTAND - 0xc09 */
+/* was: DCC_NOSTRANGERFILES1 - 0xc0a */
+/* was: DCC_NOSTRANGERFILES2 - 0xc0b */
 #define DCC_TOOMANYDCCS1	get_language(0xc0c)
 #define DCC_TOOMANYDCCS2	get_language(0xc0d)
-#define DCC_DCCNOTSUPPORTED	get_language(0xc0e)
-#define DCC_REFUSEDNODCC	get_language(0xc0f)
-#define DCC_REFUSEDNODCC_ARGS	param, nick, from
-#define DCC_FILENAMEBADSLASH	get_language(0xc10)
-#define DCC_MISSINGFILESIZE	get_language(0xc11)
-#define DCC_FILEEXISTS		get_language(0xc12)
-#define DCC_CREATEERROR		get_language(0xc13)
-#define DCC_FILEBEINGSENT	get_language(0xc14)
-#define DCC_REFUSEDNODCC2	get_language(0xc15)
-#define DCC_REFUSEDNODCC3	get_language(0xc16)
-#define DCC_FILETOOLARGE	get_language(0xc17)
-#define DCC_FILETOOLARGE2	get_language(0xc18)
+/* was: DCC_DCCNOTSUPPORTED - 0xc0e */
+/* was: DCC_REFUSEDNODCC - 0xc0f */
+/* was: DCC_FILENAMEBADSLASH - 0xc10 */
+/* was: DCC_MISSINGFILESIZE - 0xc11 */
+/* was: DCC_FILEEXISTS - 0xc12 */
+/* was: DCC_CREATEERROR - 0xc13 */
+/* was: DCC_FILEBEINGSENT - 0xc14 */
+/* was: DCC_REFUSEDNODCC2 - 0xc15 */
+/* was: DCC_REFUSEDNODCC3 - 0xc16 */
+/* was: DCC_FILETOOLARGE - 0xc17 */
+/* was: DCC_FILETOOLARGE2 - 0xc18 */
 #define DCC_CONNECTFAILED1	get_language(0xc19)
 #define DCC_CONNECTFAILED2	get_language(0xc1a)
-#define DCC_CONNECTFAILED3  get_language(0xc22)
-#define DCC_FILESYSBROKEN	get_language(0xc1b)
+#define DCC_CONNECTFAILED3	get_language(0xc22)
+/* was: DCC_FILESYSBROKEN - 0xc1b */
 #define DCC_ENTERPASS		get_language(0xc1c)
 #define DCC_FLOODBOOT		get_language(0xc1d)
-#define DCC_BOOTED1	get_language(0xc1e)
-#define DCC_BOOTED2	get_language(0xc1f)
-#define DCC_BOOTED2_ARGS		files ? "file section" : "bot", \
-					by, reason[0] ? ": " : ".", reason
-#define DCC_BOOTED3	get_language(0xc20)
-#define DCC_BOOTED3_ARGS	by, dcc[idx].nick, \
-                                reason[0] ? ": " : ".", reason
+#define DCC_BOOTED1		get_language(0xc1e)
+#define DCC_BOOTED2		get_language(0xc1f)
+#define DCC_BOOTED3		get_language(0xc20)
 
-/* Stuff from chan.c */
-#define CHAN_LIMBOBOT	get_language(0xd00)
+/* Stuff from chan.c
+ */
+/* was: CHAN_LIMBOBOT - 0xd00 */
 
-/* BOTNET messages */
-#define NET_FAKEREJECT	get_language(0xe00)
-#define NET_LINKEDTO	get_language(0xe01)
-#define NET_WRONGBOT	get_language(0xe02)
-#define NET_LEFTTHE	get_language(0xe03)
-#define NET_JOINEDTHE	get_language(0xe04)
-#define NET_AWAY	get_language(0xe05)
-#define NET_UNAWAY	get_language(0xe06)
-#define NET_NICKCHANGE	get_language(0xe07)
+/* BOTNET messages
+ */
+#define NET_FAKEREJECT		get_language(0xe00)
+#define NET_LINKEDTO		get_language(0xe01)
+#define NET_WRONGBOT		get_language(0xe02)
+#define NET_LEFTTHE		get_language(0xe03)
+#define NET_JOINEDTHE		get_language(0xe04)
+#define NET_AWAY		get_language(0xe05)
+#define NET_UNAWAY		get_language(0xe06)
+#define NET_NICKCHANGE		get_language(0xe07)
 
-/* Stuff from dcc.c */
-#define DCC_REJECT	get_language(0xe08)
-#define DCC_LINKED	get_language(0xe09)
-#define DCC_LINKFAIL	get_language(0xe0a)
-#define DCC_BADPASS	get_language(0xe0b)
-#define DCC_PASSREQ	get_language(0xe0c)
-#define DCC_LINKERROR	get_language(0xe0d)
-#define DCC_LOSTBOT	get_language(0xe0e)
-#define DCC_TIMEOUT	get_language(0xe0f)
-#define DCC_LOGGEDIN	get_language(0xe10)
-#define DCC_BADLOGIN	get_language(0xe11)
-#define DCC_HOUSTON	get_language(0xe12)
-#define DCC_JOIN	get_language(0xe13)
-#define DCC_LOSTDCC	get_language(0xe14)
-#define DCC_PWDTIMEOUT	get_language(0xe15)
-#define DCC_CLOSED	get_language(0xe16)
-#define DCC_FAILED	get_language(0xe17)
-#define DCC_BADSRC	get_language(0xe18)
-#define DCC_BADIP	get_language(0xe19)
-#define DCC_BADHOST	get_language(0xe1a)
-#define DCC_TELCONN	get_language(0xe1b)
-#define DCC_IDENTFAIL	get_language(0xe1c)
-#define DCC_PORTDIE	get_language(0xe1d)
-#define DCC_BADNICK	get_language(0xe1e)
-#define DCC_NONBOT	get_language(0xe1f)
-#define DCC_NONUSER	get_language(0xe20)
-#define DCC_INVHANDLE	get_language(0xe21)
-#define DCC_DUPLICATE	get_language(0xe22)
-#define DCC_NOPASS	get_language(0xe23)
-#define DCC_LOSTCON	get_language(0xe24)
-#define DCC_TTIMEOUT	get_language(0xe25)
-#define DCC_INSTCOMPL	get_language(0xe26)
-#define DCC_NEWUSER	get_language(0xe27)
-#define DCC_LOSTNEWUSER	get_language(0xe28)
-#define DCC_LOSTNEWUSR2	get_language(0xe29)
-#define DCC_TIMEOUTUSER	get_language(0xe2a)
-#define DCC_TIMEOUTUSR2	get_language(0xe2b)
-#define DCC_TCLERROR	get_language(0xe2c)
-#define DCC_DEADSOCKET	get_language(0xe2d)
-#define DCC_LOSTCONN	get_language(0xe2e)
-#define DCC_EOFIDENT	get_language(0xe2f)
-#define DCC_LOSTIDENT	get_language(0xe30)
-#define DCC_NOACCESS	get_language(0xe31)
-#define DCC_MYBOTNETNICK get_language(0xe32)
+/* Stuff from dcc.c
+ */
+#define DCC_REJECT		get_language(0xe08)
+#define DCC_LINKED		get_language(0xe09)
+#define DCC_LINKFAIL		get_language(0xe0a)
+#define DCC_BADPASS		get_language(0xe0b)
+#define DCC_PASSREQ		get_language(0xe0c)
+#define DCC_LINKERROR		get_language(0xe0d)
+#define DCC_LOSTBOT		get_language(0xe0e)
+#define DCC_TIMEOUT		get_language(0xe0f)
+#define DCC_LOGGEDIN		get_language(0xe10)
+#define DCC_BADLOGIN		get_language(0xe11)
+#define DCC_HOUSTON		get_language(0xe12)
+#define DCC_JOIN		get_language(0xe13)
+#define DCC_LOSTDCC		get_language(0xe14)
+#define DCC_PWDTIMEOUT		get_language(0xe15)
+#define DCC_CLOSED		get_language(0xe16)
+#define DCC_FAILED		get_language(0xe17)
+#define DCC_BADSRC		get_language(0xe18)
+/* was: DCC_BADIP 0xe19 */
+#define DCC_BADHOST		get_language(0xe1a)
+#define DCC_TELCONN		get_language(0xe1b)
+#define DCC_IDENTFAIL		get_language(0xe1c)
+#define DCC_PORTDIE		get_language(0xe1d)
+#define DCC_BADNICK		get_language(0xe1e)
+#define DCC_NONBOT		get_language(0xe1f)
+#define DCC_NONUSER		get_language(0xe20)
+#define DCC_INVHANDLE		get_language(0xe21)
+#define DCC_DUPLICATE		get_language(0xe22)
+#define DCC_NOPASS		get_language(0xe23)
+#define DCC_LOSTCON		get_language(0xe24)
+#define DCC_TTIMEOUT		get_language(0xe25)
+#define DCC_INSTCOMPL		get_language(0xe26)
+#define DCC_NEWUSER		get_language(0xe27)
+#define DCC_LOSTNEWUSER		get_language(0xe28)
+#define DCC_LOSTNEWUSR2		get_language(0xe29)
+#define DCC_TIMEOUTUSER		get_language(0xe2a)
+#define DCC_TIMEOUTUSR2		get_language(0xe2b)
+#define DCC_TCLERROR		get_language(0xe2c)
+#define DCC_DEADSOCKET		get_language(0xe2d)
+#define DCC_LOSTCONN		get_language(0xe2e)
+#define DCC_EOFIDENT		get_language(0xe2f)
+#define DCC_LOSTIDENT		get_language(0xe30)
+#define DCC_NOACCESS		get_language(0xe31)
+#define DCC_MYBOTNETNICK	get_language(0xe32)
+#define DCC_LOSTDUP		get_language(0xe33)
 
 #endif				/* _EGG_LANG_H */

+ 125 - 132
src/language.c

@@ -1,32 +1,32 @@
-/* 
+/*
  * language.c -- handles:
  *   language support code
- * 
- * $Id: language.c,v 1.13 2000/01/08 21:23:14 per Exp $
+ *
+ * $Id: language.c,v 1.17 2002/01/16 03:24:17 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
  */
 
-/* 
+/*
  * DOES:
  *              Nothing <- typical BB code :)
- * 
+ *
  * ENVIRONMENT VARIABLES:
  *              EGG_LANG       - language to use (default: "english")
  *              EGG_LANGDIR    - directory with all lang files
@@ -42,12 +42,12 @@
  *              DCC .relang
  *              DCC .ldump
  *              DCC .lstat
- * 
+ *
  * FILE FORMAT: language.lang
  *              <textidx>,<text>
  * TEXT MESSAGE USAGE:
  *              get_language(<textidx> [,<PARMS>])
- * 
+ *
  * ADDING LANGUAGES:
  *              o       Copy an existing <section>.<oldlanguage>.lang to a
  *                      new .lang file and modify as needed.
@@ -60,12 +60,13 @@
  *              o       Create a <newsection>.english.lang file.
  *              o       Add add_lang_section("<newsection>"); to your module
  *                      startup function.
- * 
+ *
  */
 
 #include "main.h"
 
-extern struct dcc_t *dcc;
+extern struct dcc_t	*dcc;
+
 
 typedef struct lang_st {
   struct lang_st *next;
@@ -84,9 +85,9 @@ typedef struct lang_t {
   struct lang_t *next;
 } lang_tab;
 
-static lang_tab *langtab[64];
-static lang_sec *langsection = NULL;
-static lang_pri *langpriority = NULL;
+static lang_tab	*langtab[64];
+static lang_sec	*langsection = NULL;
+static lang_pri	*langpriority = NULL;
 
 static int del_lang(char *);
 static int add_message(int, char *);
@@ -94,24 +95,24 @@ static void recheck_lang_sections(void);
 static void read_lang(char *);
 void add_lang_section(char *);
 int del_lang_section(char *);
+int exist_lang_section(char *);
 static char *get_specific_langfile(char *, lang_sec *);
 static char *get_langfile(lang_sec *);
 static int split_lang(char *, char **, char **);
 int cmd_loadlanguage(struct userrec *, int, char *);
 
 
-/* add a new preferred language to the list of languages. Newly added
+/* Add a new preferred language to the list of languages. Newly added
  * languages get the highest priority.
  */
 void add_lang(char *lang)
 {
   lang_pri *lp = langpriority, *lpo = NULL;
 
-  Context;
   while (lp) {
-    /* the language already exists, moving to the beginning */
+    /* The language already exists, moving to the beginning */
     if (!strcmp(lang, lp->lang)) {
-      /* already at the front? */
+      /* Already at the front? */
       if (!lpo)
 	return;
       lpo->next = lp->next;
@@ -123,27 +124,27 @@ void add_lang(char *lang)
     lp = lp->next;
   }
 
-  /* no existing entry, create a new one */
+  /* No existing entry, create a new one */
   lp = nmalloc(sizeof(lang_pri));
   lp->lang = nmalloc(strlen(lang) + 1);
   strcpy(lp->lang, lang);
   lp->next = NULL;
 
-  /* if we have other entries, point to the beginning of the old list */
+  /* If we have other entries, point to the beginning of the old list */
   if (langpriority)
     lp->next = langpriority;
   langpriority = lp;
-  putlog(LOG_MISC, "*", "LANG: Language loaded: %s", lang);
+  debug1("LANG: Language loaded: %s", lang);
 }
 
-/* remove a language from the list of preferred languages. */
+/* Remove a language from the list of preferred languages.
+ */
 static int del_lang(char *lang)
 {
   lang_pri *lp = langpriority, *lpo = NULL;
 
-  Context;
   while (lp) {
-    /* found the language? */
+    /* Found the language? */
     if (!strcmp(lang, lp->lang)) {
       if (lpo)
 	lpo->next = lp->next;
@@ -152,14 +153,13 @@ static int del_lang(char *lang)
       if (lp->lang)
         nfree(lp->lang);
       nfree(lp);
-      putlog(LOG_MISC, "*", "LANG: Language unloaded: %s",
-	     lang); 
+      debug1("LANG: Language unloaded: %s", lang);
       return 1;
     }
     lpo = lp;
     lp = lp->next;
   }
-  /* language not found */
+  /* Language not found */
   return 0;
 }
 
@@ -190,29 +190,26 @@ static int add_message(int lidx, char *ltext)
   return 0;
 }
 
-/* recheck all sections and check if any language files are available
+/* Recheck all sections and check if any language files are available
  * which match the preferred language(s) more closely
  */
 static void recheck_lang_sections(void)
 {
-  lang_sec *ls = langsection;
+  lang_sec *ls;
   char *langfile;
 
-  Context;
-  while (ls) {
-    if (ls->section) {
+  for (ls = langsection; ls && ls->section; ls = ls->next) {
       langfile = get_langfile(ls);
-      /* found a language with a more preferred language? */
+      /* Found a language with a more preferred language? */
       if (langfile) {
         read_lang(langfile);
         nfree(langfile);
       }
     }
-    ls = ls->next;
-  }
 }
 
-/* parse a language file */
+/* Parse a language file
+ */
 static void read_lang(char *langfile)
 {
   FILE *FLANG;
@@ -225,7 +222,6 @@ static void read_lang(char *langfile)
   int ltexts = 0;
   int ladd = 0, lupdate = 0;
 
-  Context;
   FLANG = fopen(langfile, "r");
   if (FLANG == NULL) {
     putlog(LOG_MISC, "*", "LANG: unexpected: reading from file %s failed.",
@@ -239,7 +235,11 @@ static void read_lang(char *langfile)
     if (lbuf[0] != '#' || lskip) {
       ltext = nrealloc(ltext, 512);
       if (sscanf(lbuf, "%s", ltext) != EOF) {
+#ifdef LIBSAFE_HACKS
+	if (sscanf(lbuf, "0x%x,%500c", &lidx, ltext) != 1) {
+#else
 	if (sscanf(lbuf, "0x%x,%500c", &lidx, ltext) != 2) {
+#endif
 	  putlog(LOG_MISC, "*", "Malformed text line in %s at %d.",
 		 langfile, lline);
 	} else {
@@ -257,14 +257,18 @@ static void read_lang(char *langfile)
 	    }
 	  }
 	}
-	/* We gotta fix \n's here as, being arguments to sprintf(), */
-	/* they won't get translated */
+	/* We gotta fix \n's here as, being arguments to sprintf(),
+	 * they won't get translated.
+	 */
 	ctmp = ltext;
 	ctmp1 = ltext;
 	while (*ctmp1) {
-	  if (*ctmp1 == '\\' && *(ctmp1 + 1) == 'n') {
+	  if ((*ctmp1 == '\\') && (*(ctmp1 + 1) == 'n')) {
 	    *ctmp = '\n';
 	    ctmp1++;
+	  } else if ((*ctmp1 == '\\') && (*(ctmp1 + 1) == 't')) {
+	    *ctmp = '\t';
+	    ctmp1++;
 	  } else
 	    *ctmp = *ctmp1;
 	  ctmp++;
@@ -285,10 +289,21 @@ static void read_lang(char *langfile)
   nfree(ltext);
   fclose(FLANG);
 
-  putlog(LOG_MISC, "*", "LANG: %d messages of %d lines loaded from %s",
-	 ltexts, lline, langfile);
-  putlog(LOG_MISC, "*", "LANG: %d adds, %d updates to message table",
-	 ladd, lupdate);
+  debug3("LANG: %d messages of %d lines loaded from %s", ltexts, lline,
+	 langfile);
+  debug2("LANG: %d adds, %d updates to message table", ladd, lupdate);
+}
+
+/* Returns 1 if the section exists, otherwise 0.
+ */
+int exist_lang_section(char *section)
+{
+  lang_sec *ls;
+
+  for (ls = langsection; ls; ls = ls->next)
+    if (!strcmp(section, ls->section))
+      return 1;
+  return 0;
 }
 
 /* Add a new language section. e.g. section "core"
@@ -296,32 +311,29 @@ static void read_lang(char *langfile)
  */
 void add_lang_section(char *section)
 {
-  char *langfile = NULL;
-  lang_sec *ls = langsection, *ols = NULL;
-  int ok = 0;
+  char		*langfile = NULL;
+  lang_sec	*ls, *ols = NULL;
+  int		 ok = 0;
 
-  Context;
-  while (ls) {
-    /* already know of that section? */
+  for (ls = langsection; ls; ols = ls, ls = ls->next)
+    /* Already know of that section? */
     if (!strcmp(section, ls->section))
       return;
-    ols = ls;
-    ls = ls->next;
-  }
 
-  /* create new section entry */
+  /* Create new section entry */
   ls = nmalloc(sizeof(lang_sec));
   ls->section = nmalloc(strlen(section) + 1);
   strcpy(ls->section, section);
   ls->lang = NULL;
   ls->next = NULL;
 
-  /* connect to existing list of sections */
+  /* Connect to existing list of sections */
   if (ols)
     ols->next = ls;
   else
     langsection = ls;
-  putlog(LOG_MISC, "*", "LANG: Section loaded: %s", section);  
+  debug1("LANG: Section loaded: %s", section);
+
   /* Always load base language */
   langfile = get_specific_langfile(BASELANG, ls);
   if (langfile) {
@@ -334,7 +346,7 @@ void add_lang_section(char *section)
   if (!langfile) {
     if (!ok)
       putlog(LOG_MISC, "*", "LANG: No lang files found for section %s.",
-           section);
+	     section);
     return;
   }
   read_lang(langfile);
@@ -343,9 +355,9 @@ void add_lang_section(char *section)
 
 int del_lang_section(char *section)
 {
-  lang_sec *ls = langsection, *ols = NULL;
+  lang_sec *ls, *ols;
 
-  while (ls) {
+  for (ls = langsection, ols = NULL; ls; ols = ls, ls = ls->next)
     if (ls->section && !strcmp(ls->section, section)) {
       if (ols)
 	ols->next = ls->next;
@@ -355,12 +367,9 @@ int del_lang_section(char *section)
       if (ls->lang)
 	nfree(ls->lang);
       nfree(ls);
-      putlog(LOG_MISC, "*", "LANG: Section unloaded: %s", section);
+      debug1("LANG: Section unloaded: %s", section);
       return 1;
     }
-    ols = ls;
-    ls = ls->next;
-  }
   return 0;
 }
 
@@ -377,7 +386,7 @@ static char *get_specific_langfile(char *language, lang_sec *sec)
   sfile = fopen(langfile, "r");
   if (sfile) {
     fclose(sfile);
-    /* save language used for this section */
+    /* Save language used for this section */
     sec->lang = nrealloc(sec->lang, strlen(language) + 1);
     strcpy(sec->lang, language);
     return langfile;
@@ -392,20 +401,17 @@ static char *get_specific_langfile(char *language, lang_sec *sec)
 static char *get_langfile(lang_sec *sec)
 {
   char *langfile;
-  lang_pri *lp = langpriority;
+  lang_pri *lp;
 
-  Context;
-  while (lp) {
-    /* there is no need to reload the same language */
-    if (sec->lang && !strcmp(sec->lang, lp->lang)) {
+  for (lp = langpriority; lp; lp = lp->next) {
+    /* There is no need to reload the same language */
+    if (sec->lang && !strcmp(sec->lang, lp->lang))
       return NULL;
-    }
     langfile = get_specific_langfile(lp->lang, sec);
     if (langfile)
       return langfile;
-    lp = lp->next;
   }
-  /* we did not find any files, clear the language field */
+  /* We did not find any files, clear the language field */
   if (sec->lang)
     nfree(sec->lang);
   sec->lang = NULL;
@@ -420,7 +426,6 @@ static int split_lang(char *par, char **lang, char **section)
 {
   char *p;
 
-  Context;
   p = strrchr(par, '/');
   /* path attached? */
   if (p)
@@ -439,12 +444,12 @@ static int split_lang(char *par, char **lang, char **section)
   return 1;
 }
 
-/* compability function to allow users/modules to use the old command. */
+/* Compability function to allow users/modules to use the old command.
+ */
 int cmd_loadlanguage(struct userrec *u, int idx, char *par)
 {
   char *section, *lang, *buf;
 
-  Context;
   dprintf(idx, "Note: This command is obsoleted by +lang.\n");
   if (!par || !par[0]) {
     dprintf(idx, "Usage: language <section>.<language>\n");
@@ -468,7 +473,6 @@ int cmd_loadlanguage(struct userrec *u, int idx, char *par)
 
 static int cmd_plslang(struct userrec *u, int idx, char *par)
 {
-  Context;
   if (!par || !par[0]) {
     dprintf(idx, "Usage: +lang <language>\n");
     return 0;
@@ -481,7 +485,6 @@ static int cmd_plslang(struct userrec *u, int idx, char *par)
 
 static int cmd_mnslang(struct userrec *u, int idx, char *par)
 {
-  Context;
   if (!par || !par[0]) {
     dprintf(idx, "Usage: -lang <language>\n");
     return 0;
@@ -496,7 +499,6 @@ static int cmd_mnslang(struct userrec *u, int idx, char *par)
 
 static int cmd_plslsec(struct userrec *u, int idx, char *par)
 {
-  Context;
   if (!par || !par[0]) {
     dprintf(idx, "Usage: +lsec <section>\n");
     return 0;
@@ -508,7 +510,6 @@ static int cmd_plslsec(struct userrec *u, int idx, char *par)
 
 static int cmd_mnslsec(struct userrec *u, int idx, char *par)
 {
-  Context;
   if (!par || !par[0]) {
     dprintf(idx, "Usage: -lsec <section>\n");
     return 0;
@@ -532,7 +533,6 @@ static int cmd_languagedump(struct userrec *u, int idx, char *par)
   char ltext2[512];
   int idx2, i;
 
-  Context;
   putlog(LOG_CMDS, "*", "#%s# ldump %s", dcc[idx].nick, par);
   if (par[0]) {
     /* atoi (hence strtol) don't work right here for hex */
@@ -554,59 +554,54 @@ static int cmd_languagedump(struct userrec *u, int idx, char *par)
 static char text[512];
 char *get_language(int idx)
 {
-  lang_tab *l = langtab[idx & 63];
+  lang_tab *l;
 
   if (!idx)
     return "MSG-0-";
-  while (l) {
+  for (l = langtab[idx & 63]; l; l = l->next)
     if (idx == l->idx)
       return l->text;
-    l = l->next;
-  }
-  sprintf(text, "MSG%03X", idx);
+  egg_snprintf(text, sizeof text, "MSG%03X", idx);
   return text;
 }
 
 int expmem_language()
 {
   lang_tab *l;
-  lang_sec *ls = langsection;
-  lang_pri *lp = langpriority;
+  lang_sec *ls;
+  lang_pri *lp;
   int i, size = 0;
 
-  Context;
   for (i = 0; i < 64; i++)
     for (l = langtab[i]; l; l = l->next) {
       size += sizeof(lang_tab);
       size += (strlen(l->text) + 1);
     }
-  while (ls) {
+  for (ls = langsection; ls; ls = ls->next) {
     size += sizeof(lang_sec);
     if (ls->section)
       size += strlen(ls->section)+1;
     if (ls->lang)
       size += strlen(ls->lang)+1;
-    ls = ls->next;
   }
-  while (lp) {
+  for (lp = langpriority; lp; lp = lp->next) {
     size += sizeof(lang_pri);
     if (lp->lang)
       size += strlen(lp->lang)+1;
-    lp = lp->next;
   }
   return size;
 }
 
-/* a report on the module status - not sure if we need this now :/ */
+/* A report on the module status - only for debugging purposes
+ */
 static int cmd_languagestatus(struct userrec *u, int idx, char *par)
 {
-  int ltexts = 0;  
+  int ltexts = 0;
   register int i, c, maxdepth = 0, used = 0, empty = 0;
   lang_tab *l;
   lang_sec *ls = langsection;
   lang_pri *lp = langpriority;
 
-  Context;
   putlog(LOG_CMDS, "*", "#%s# lstat %s", dcc[idx].nick, par);
   for (i = 0; i < 64; i++) {
     c = 0;
@@ -620,7 +615,6 @@ static int cmd_languagestatus(struct userrec *u, int idx, char *par)
       empty++;
     ltexts += c;
   }
-  Context;
   dprintf(idx, "Language code report:\n");
   dprintf(idx, "   Table size   : %d bytes\n", expmem_language());
   dprintf(idx, "   Text messages: %d\n", ltexts);
@@ -628,32 +622,31 @@ static int cmd_languagestatus(struct userrec *u, int idx, char *par)
 	  used, empty, maxdepth, (float) ltexts / 64.0);
   if (lp) {
     int c = 0;
-    
+
     dprintf(idx, "   Supported languages:");
-    while (lp) {
+    for (; lp; lp = lp->next) {  
       dprintf(idx, "%s %s", c ? "," : "", lp->lang);
       c = 1;
-      lp = lp->next;
     }
     dprintf(idx, "\n");
   }
   if (ls) {
     dprintf(idx, "\n   SECTION              LANG\n");
     dprintf(idx, "   ==============================\n");
-
-    while (ls) {
+    for (; ls; ls = ls->next)
       dprintf(idx, "   %-20s %s\n", ls->section,
 	      ls->lang ? ls->lang : "<none>");
-      ls = ls->next;
-    }
   }
   return 0;
 }
 
-/* compability function to allow scripts to use the old command. */
+/* Compability function to allow scripts to use the old command.
+ */
 static int tcl_language STDVAR
 {
   char *lang, *section, *buf;
+
+  putlog(LOG_MISC, "*", "The Tcl command 'language' is obsolete. Use 'addlang' instead.");
   BADARGS(2, 2, " language");
 
   buf = nmalloc(strlen(argv[1])+1);
@@ -673,7 +666,7 @@ static int tcl_language STDVAR
 static int tcl_plslang STDVAR
 {
   BADARGS(2, 2, " language");
-  
+
   add_lang(argv[1]);
   recheck_lang_sections();
 
@@ -681,7 +674,7 @@ static int tcl_plslang STDVAR
 }
 
 static int tcl_mnslang STDVAR
-{ 
+{
   BADARGS(2, 2, " language");
 
   if (!del_lang(argv[1])) {
@@ -694,7 +687,7 @@ static int tcl_mnslang STDVAR
 }
 
 static int tcl_addlangsection STDVAR
-{ 
+{
   BADARGS(2, 2, " section");
 
   add_lang_section(argv[1]);
@@ -702,7 +695,7 @@ static int tcl_addlangsection STDVAR
 }
 
 static int tcl_dellangsection STDVAR
-{ 
+{
   BADARGS(2, 2, " section");
 
   if (!del_lang_section(argv[1])) {
@@ -720,26 +713,26 @@ static int tcl_relang STDVAR
 
 static cmd_t langdcc[] =
 {
-  {"language", "n", cmd_loadlanguage, NULL},
-  {"+lang", "n", cmd_plslang, NULL},
-  {"-lang", "n", cmd_mnslang, NULL},
-  {"+lsec", "n", cmd_plslsec, NULL},
-  {"-lsec", "n", cmd_mnslsec, NULL},
-  {"ldump", "n", cmd_languagedump, NULL},
-  {"lstat", "n", cmd_languagestatus, NULL},
-  {"relang", "n", cmd_relang, NULL},
-  {0, 0, 0, 0}
+  {"language",	"n",	cmd_loadlanguage,	NULL},
+  {"+lang",	"n",	cmd_plslang,		NULL},
+  {"-lang",	"n",	cmd_mnslang,		NULL},
+  {"+lsec",	"n",	cmd_plslsec,		NULL},
+  {"-lsec",	"n",	cmd_mnslsec,		NULL},
+  {"ldump",	"n",	cmd_languagedump,	NULL},
+  {"lstat",	"n",	cmd_languagestatus,	NULL},
+  {"relang",	"n",	cmd_relang,		NULL},
+  {NULL,	NULL,	NULL,			NULL}
 };
 
 static tcl_cmds langtcls[] =
 {
-  {"language", tcl_language},
-  {"addlang", tcl_plslang},
-  {"dellang", tcl_mnslang},
-  {"addlangsection", tcl_addlangsection},
-  {"dellangsection", tcl_dellangsection},
-  {"relang", tcl_relang},
-  {0, 0}
+  {"language",		tcl_language},
+  {"addlang",		tcl_plslang},
+  {"dellang",		tcl_mnslang},
+  {"addlangsection",	tcl_addlangsection},
+  {"dellangsection",	tcl_dellangsection},
+  {"relang",		tcl_relang},
+  {NULL,		NULL}
 };
 
 void init_language(int flag)
@@ -747,13 +740,13 @@ void init_language(int flag)
   int i;
   char *deflang;
 
-  Context;
   if (flag) {
     for (i = 0; i < 32; i++)
       langtab[i] = 0;
-    /* The default language is always "english" as language files are
-     * gauranteed to exist in english. */
-    add_lang("english");
+    /* The default language is always BASELANG as language files are
+     * gauranteed to exist in that language.
+     */
+    add_lang(BASELANG);
     /* Let the user choose a different, preferred language */
     deflang = getenv("EGG_LANG");
     if (deflang)

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 336 - 256
src/main.c


+ 42 - 38
src/main.h

@@ -1,23 +1,23 @@
-/* 
+/*
  * main.h
  *   include file to include most other include files
- * 
- * $Id: main.h,v 1.13 2000/01/29 12:45:28 per Exp $
+ *
+ * $Id: main.h,v 1.19 2002/01/02 03:46:35 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -26,10 +26,8 @@
 #ifndef _EGG_MAIN_H
 #define _EGG_MAIN_H
 
-#ifndef MAKING_MODS
-#  ifdef HAVE_CONFIG_H
-#    include "../config.h"
-#  endif
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
 #endif
 
 /* UGH! Why couldn't Tcl pick a standard? */
@@ -51,11 +49,6 @@
 #  define EGG_VARARGS_START(type, name, list) (va_start(list), va_arg(list,type))
 #endif
 
-/* For pre Tcl7.5p1 versions */
-#ifndef HAVE_TCL_FREE
-#  define Tcl_Free(x) n_free(x, "", 0)
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -63,6 +56,7 @@
 #  include <strings.h>
 #endif
 #include <sys/types.h>
+#include "lush.h"
 #include "lang.h"
 #include "eggdrop.h"
 #include "flags.h"
@@ -74,39 +68,49 @@
 #include "tclhash.h"
 #include "chan.h"
 #include "users.h"
+#include "compat/compat.h"
+
+/* For pre Tcl7.5p1 versions */
+#ifndef HAVE_TCL_FREE
+#  define Tcl_Free(x) n_free(x, "", 0)
+#endif
+
+/* For pre7.6 Tcl versions */
+#ifndef TCL_PATCH_LEVEL
+#  define TCL_PATCH_LEVEL Tcl_GetVar(interp, "tcl_patchLevel", TCL_GLOBAL_ONLY)
+#endif
 
 #ifndef MAKING_MODS
 extern struct dcc_table DCC_CHAT, DCC_BOT, DCC_LOST, DCC_SCRIPT, DCC_BOT_NEW,
  DCC_RELAY, DCC_RELAYING, DCC_FORK_RELAY, DCC_PRE_RELAY, DCC_CHAT_PASS,
  DCC_FORK_BOT, DCC_SOCKET, DCC_TELNET_ID, DCC_TELNET_NEW, DCC_TELNET_PW,
- DCC_TELNET, DCC_IDENT, DCC_IDENTWAIT;
+ DCC_TELNET, DCC_IDENT, DCC_IDENTWAIT, DCC_DNSWAIT;
 
 #endif
 
-/* from net.h */
+#define iptolong(a)		(0xffffffff & 				\
+				 (long) (htonl((unsigned long) a)))
+#define fixcolon(x)		do {					\
+	if ((x)[0] == ':')			 			\
+		(x)++;							\
+	else								\
+		(x) = newsplit(&(x));					\
+} while (0)
 
-/* my own byte swappers */
-#ifdef WORDS_BIGENDIAN
-#  define swap_short(sh) (sh)
-#  define swap_long(ln) (ln)
-#else
-#  define swap_short(sh) ((((sh) & 0xff00) >> 8) | (((sh) & 0x00ff) << 8))
-#  define swap_long(ln) (swap_short(((ln)&0xffff0000)>>16) | (swap_short((ln)&0x0000ffff)<<16))
-#endif
-#define iptolong(a) (0xffffffff & (long)(swap_long((unsigned long)a)))
-#define fixcolon(x) if (x[0]==':') {x++;} else {x=newsplit(&x);}
+/* This macro copies (_len - 1) bytes from _source to _target. The
+ * target string is NULL-terminated.
+ */
+#define strncpyz(_target, _source, _len)	do {			\
+	strncpy((_target), (_source), (_len) - 1);			\
+	(_target)[(_len) - 1] = 0;					\
+} while (0)
 
-/* Stupid Borg Cube crap ;p */
 #ifdef BORGCUBES
 
-/* net.h needs this */
-#define O_NONBLOCK      00000004	/* POSIX non-blocking I/O       */
+/* For net.c */
+#  define O_NONBLOCK	00000004    /* POSIX non-blocking I/O		   */
 
-/* mod/filesys.mod/filedb.c needs this */
-#define _S_IFMT         0170000		/* type of file */
-#define _S_IFDIR        0040000		/*   directory */
-#define S_ISDIR(m)      (((m)&(_S_IFMT)) == (_S_IFDIR))
+#endif				/* BORGUBES */
 
-#endif				/* BORGCUBES */
 
 #endif				/* _EGG_MAIN_H */

+ 3 - 3
src/match.c

@@ -3,7 +3,7 @@
  *   wildcard matching functions
  *   (rename to reg.c for ircII)
  * 
- * $Id: match.c,v 1.5 1999/12/22 20:30:03 guppy Exp $
+ * $Id: match.c,v 1.5 2000/01/30 19:26:20 fabian Exp $
  */
 /* 
  * Once this code was working, I added support for % so that I could
@@ -264,9 +264,9 @@ int _wild_match(register unsigned char *m, register unsigned char *n)
     return NOMATCH;
   /* find the end of each string */
   while (*(++m));
-  m--;
+    m--;
   while (*(++n));
-  n--;
+    n--;
 
   while (n >= na) {
     if ((m <= ma) || (m[-1] != QUOTE)) {	/* Only look if no quote */

+ 20 - 5
src/md5/Makefile.in

@@ -1,8 +1,10 @@
 # Makefile for src/md5/
-# $Id: Makefile.in,v 1.4 1999/12/15 02:32:58 guppy Exp $
+# $Id: Makefile.in,v 1.9 2000/09/12 15:26:51 fabian Exp $
 
-SHELL = /bin/sh
+SHELL = @SHELL@
 top_srcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
 
 @SET_MAKE@
 INSTALL = @INSTALL@
@@ -10,16 +12,22 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 
+CC = @CC@
+LD = @CC@
+STRIP = @STRIP@
+CFLAGS = @CFLAGS@ -I. -I../.. -I$(top_srcdir) -I$(top_srcdir)/src @DEFS@ $(CFLGS)
+CPPFLAGS = @CPPFLAGS@
+
 OBJS = md5c.o
 
 doofus:
 	@echo ""
 	@echo "Let's try this from the right directory..."
 	@echo ""
-	@cd $(top_srcdir); $(MAKE)
+	@cd ../.. && $(MAKE)
 
 depend:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -MM *.c > .depend
+	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/*.c > .depend
 
 clean:
 	@rm -f .depend *.o *~
@@ -33,4 +41,11 @@ md5: $(OBJS)
 	$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
 
 #safety hash
-md5c.o: md5c.c global.h md5.h
+md5c.o: ./md5c.c ../../src/main.h ../../config.h ../../src/lang.h \
+ ../../src/eggdrop.h ../../src/flags.h ../../src/proto.h ../../lush.h \
+ ../../src/misc_file.h ../../src/cmdt.h ../../src/tclegg.h \
+ ../../src/tclhash.h ../../src/chan.h ../../src/users.h \
+ ../../src/compat/compat.h ../../src/compat/inet_aton.h \
+ ../../src/compat/snprintf.h ../../src/compat/memset.h \
+ ../../src/compat/memcpy.h ../../src/compat/strcasecmp.h \
+ ../../src/compat/strftime.h md5.h

+ 0 - 40
src/md5/global.h

@@ -1,40 +0,0 @@
-/* 
- * global.h
- *   RSAREF types and constants
- * 
- * $Id: global.h,v 1.4 1999/12/22 20:30:03 guppy Exp $
- */
-
-#ifndef _EGG_MD5_GLOBAL_H
-#define _EGG_MD5_GLOBAL_H
-
-/* 
- * PROTOTYPES should be set to one if and only if the compiler
- * supports function argument prototyping.
- */
-/* 
- * The following makes PROTOTYPES default to 1 if it has not
- * already been defined with C compiler flags.
- */
-#ifndef PROTOTYPES
-#  define PROTOTYPES 1
-#endif
-
-/* POINTER defines a generic pointer type */
-typedef unsigned char *POINTER;
-
-/* UINT4 defines a four byte word */
-typedef u_32bit_t UINT4;
-
-/* 
- * PROTO_LIST is defined depending on how PROTOTYPES is defined above.
- * If using PROTOTYPES, then PROTO_LIST returns the list,
- * otherwise it returns an empty list.
- */
-#if PROTOTYPES
-#  define PROTO_LIST(list) list
-#else
-#  define PROTO_LIST(list) ()
-#endif
-
-#endif				/* _EGG_MD5_GLOBAL_H */

+ 19 - 39
src/md5/md5.h

@@ -1,46 +1,26 @@
-/* 
- * md5.h
- *   header file for md5c.c
- * 
- * $Id: md5.h,v 1.3 1999/12/22 20:30:03 guppy Exp $
- */
-/* 
- * Copyright (C) 1991, 1992  RSA Data Security, Inc.
- * Created 1991.
- * All rights reserved.
- * 
- * License to copy and use this software is granted provided that it
- * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
- * Algorithm" in all material mentioning or referencing this software
- * or this function.
- * 
- * License is also granted to make and use derivative works provided
- * that such works are identified as "derived from the RSA Data
- * Security, Inc. MD5 Message-Digest Algorithm" in all material
- * mentioning or referencing the derived work.
- * 
- * RSA Data Security, Inc. makes no representations concerning either
- * the merchantability of this software or the suitability of this
- * software for any particular purpose. It is provided "as is"
- * without express or implied warranty of any kind.
- * 
- * These notices must be retained in any copies of any part of this
- * documentation and/or software.
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security,
+ * Inc. MD5 Message-Digest Algorithm.
+ *
+ * Written by Solar Designer <solar@openwall.com> in 2001, and placed in
+ * the public domain.  See md5c.c for more information.
  */
 
-#ifndef _EGG_MD5_MD5_H
-#define _EGG_MD5_MD5_H
+#ifndef _MD5_H
+#define _MD5_H
+
+/* Any 32-bit or wider integer data type will do */
+typedef unsigned long MD5_u32plus;
 
-/* MD5 context. */
 typedef struct {
-  UINT4 state[4];                                   /* state (ABCD) */
-  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
-  unsigned char buffer[64];                         /* input buffer */
+	MD5_u32plus lo, hi;
+	MD5_u32plus a, b, c, d;
+	unsigned char buffer[64];
+	MD5_u32plus block[16];
 } MD5_CTX;
 
-void MD5Init PROTO_LIST ((MD5_CTX *));
-void MD5Update PROTO_LIST
-  ((MD5_CTX *, unsigned char *, unsigned int));
-void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+extern void MD5_Init(MD5_CTX *ctx);
+extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size);
+extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
 
-#endif				/* _EGG_MD5_MD5_H */
+#endif

+ 242 - 324
src/md5/md5c.c

@@ -1,352 +1,270 @@
-/* 
- * md5c.c
- *   RSA Data Security, Inc., MD5 message-digest algorithm
- * 
- * $Id: md5c.c,v 1.3 1999/12/15 02:32:58 guppy Exp $
- */
-/* 
- * Copyright (C) 1991, 1992  RSA Data Security, Inc.
- * Created 1991.
- * All rights reserved.
- * 
- * License to copy and use this software is granted provided that it
- * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
- * Algorithm" in all material mentioning or referencing this software
- * or this function.
- * 
- * License is also granted to make and use derivative works provided
- * that such works are identified as "derived from the RSA Data
- * Security, Inc. MD5 Message-Digest Algorithm" in all material
- * mentioning or referencing the derived work.
- * 
- * RSA Data Security, Inc. makes no representations concerning either
- * the merchantability of this software or the suitability of this
- * software for any particular purpose. It is provided "as is"
- * without express or implied warranty of any kind.
- * 
- * These notices must be retained in any copies of any part of this
- * documentation and/or software.
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security,
+ * Inc. MD5 Message-Digest Algorithm.
+ *
+ * Written by Solar Designer <solar@openwall.com> in 2001, and placed in
+ * the public domain.
+ *
+ * This differs from Colin Plumb's older public domain implementation in
+ * that no 32-bit integer data type is required, there's no compile-time
+ * endianness configuration, and the function prototypes match OpenSSL's.
+ * The primary goals are portability and ease of use.
+ *
+ * This implementation is meant to be fast, but not as fast as possible.
+ * Some known optimizations are not included to reduce source code size
+ * and avoid compile-time configuration.
  */
 
-#ifdef HAVE_CONFIG_H
-#  include "../../config.h"
-#endif
-#include "main.h"
-#include "eggdrop.h"
-#include "global.h"
+#include <string.h>
+
 #include "md5.h"
 
-/* 
- * Constants for MD5Transform routine.
- */
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-
-static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
-static void Encode PROTO_LIST
-  ((unsigned char *, UINT4 *, unsigned int));
-static void Decode PROTO_LIST
-  ((UINT4 *, unsigned char *, unsigned int));
-static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
-static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
-
-static unsigned char PADDING[64] = {
-  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* 
- * F, G, H and I are basic MD5 functions.
+/*
+ * The basic MD5 functions.
+ *
+ * F is optimized compared to its RFC 1321 definition just like in Colin
+ * Plumb's implementation.
  */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
+#define F(x, y, z)			((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z)			((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z)			((x) ^ (y) ^ (z))
+#define I(x, y, z)			((y) ^ ((x) | ~(z)))
 
-/* 
- * ROTATE_LEFT rotates x left n bits.
+/*
+ * The MD5 transformation for all four rounds.
  */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* 
- * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
- * Rotation is separate from addition to prevent recomputation.
+#define STEP(f, a, b, c, d, x, t, s) \
+	(a) += f((b), (c), (d)) + (x) + (t); \
+	(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
+	(a) += (b);
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures which tolerate unaligned
+ * memory accesses is just an optimization.  Nothing will break if it
+ * doesn't work.
  */
-#define FF(a, b, c, d, x, s, ac) { \
- (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
-  }
-#define GG(a, b, c, d, x, s, ac) { \
- (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
-  }
-#define HH(a, b, c, d, x, s, ac) { \
- (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
-  }
-#define II(a, b, c, d, x, s, ac) { \
- (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
-  }
-
-/* 
- * MD5 initialization.
- * Begins an MD5 operation, writing a new context.
+#if defined(__i386__) || defined(__vax__)
+#define SET(n) \
+	(*(MD5_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+	SET(n)
+#else
+#define SET(n) \
+	(ctx->block[(n)] = \
+	(MD5_u32plus)ptr[(n) * 4] | \
+	((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
+	((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
+	((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+	(ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters.  There're no alignment requirements.
  */
-void MD5Init (context)
-MD5_CTX *context;                                        /* context */
+static void *body(MD5_CTX *ctx, void *data, unsigned long size)
 {
-  context->count[0] = context->count[1] = 0;
-  /* Load magic initialization constants. */
-  context->state[0] = 0x67452301;
-  context->state[1] = 0xefcdab89;
-  context->state[2] = 0x98badcfe;
-  context->state[3] = 0x10325476;
+	unsigned char *ptr;
+	MD5_u32plus a, b, c, d;
+	MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+
+	ptr = data;
+
+	a = ctx->a;
+	b = ctx->b;
+	c = ctx->c;
+	d = ctx->d;
+
+	do {
+		saved_a = a;
+		saved_b = b;
+		saved_c = c;
+		saved_d = d;
+
+/* Round 1 */
+		STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
+		STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
+		STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
+		STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
+		STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
+		STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
+		STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
+		STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
+		STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
+		STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
+		STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
+		STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
+		STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
+		STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
+		STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
+		STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
+
+/* Round 2 */
+		STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
+		STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
+		STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
+		STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
+		STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
+		STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
+		STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
+		STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
+		STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
+		STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
+		STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
+		STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
+		STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
+		STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
+		STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
+		STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
+
+/* Round 3 */
+		STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
+		STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
+		STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
+		STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
+		STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
+		STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
+		STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
+		STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
+		STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
+		STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
+		STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
+		STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
+		STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
+		STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
+		STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
+		STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
+
+/* Round 4 */
+		STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
+		STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
+		STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
+		STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
+		STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
+		STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
+		STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
+		STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
+		STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
+		STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
+		STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
+		STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
+		STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
+		STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
+		STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
+		STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
+
+		a += saved_a;
+		b += saved_b;
+		c += saved_c;
+		d += saved_d;
+
+		ptr += 64;
+	} while (size -= 64);
+
+	ctx->a = a;
+	ctx->b = b;
+	ctx->c = c;
+	ctx->d = d;
+
+	return ptr;
 }
 
-/* 
- * MD5 block update operation.
- * Continues an MD5 message-digest operation,
- * processing another message block and updating the context.
- */
-void MD5Update (context, input, inputLen)
-MD5_CTX *context;                                        /* context */
-unsigned char *input;                                /* input block */
-unsigned int inputLen;                     /* length of input block */
+void MD5_Init(MD5_CTX *ctx)
 {
-  unsigned int i, index, partLen;
+	ctx->a = 0x67452301;
+	ctx->b = 0xefcdab89;
+	ctx->c = 0x98badcfe;
+	ctx->d = 0x10325476;
 
-  /* Compute number of bytes mod 64 */
-  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
-
-  /* Update number of bits */
-  if ((context->count[0] += ((UINT4)inputLen << 3))
-   < ((UINT4)inputLen << 3))
- context->count[1]++;
-  context->count[1] += ((UINT4)inputLen >> 29);
-
-  partLen = 64 - index;
-
-  /* Transform as many times as possible. */
-  if (inputLen >= partLen) {
- MD5_memcpy
-   ((POINTER)&context->buffer[index], (POINTER)input, partLen);
- MD5Transform (context->state, context->buffer);
-
- for (i = partLen; i + 63 < inputLen; i += 64)
-   MD5Transform (context->state, &input[i]);
-
- index = 0;
-  }
-  else
- i = 0;
-
-  /* Buffer remaining input */
-  MD5_memcpy
- ((POINTER)&context->buffer[index], (POINTER)&input[i],
-  inputLen-i);
+	ctx->lo = 0;
+	ctx->hi = 0;
 }
 
-/* 
- * MD5 finalization.
- * Ends an MD5 message-digest operation,
- * writing the the message digest and zeroizing the context.
- */
-void MD5Final (digest, context)
-unsigned char digest[16];                         /* message digest */
-MD5_CTX *context;                                        /* context */
+void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size)
 {
-  unsigned char bits[8];
-  unsigned int index, padLen;
-
-  /* Save number of bits */
-  Encode (bits, context->count, 8);
+	MD5_u32plus saved_lo;
+	unsigned long used, free;
 
-  /* Pad out to 56 mod 64. */
-  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
-  padLen = (index < 56) ? (56 - index) : (120 - index);
-  MD5Update (context, PADDING, padLen);
+	saved_lo = ctx->lo;
+	if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+		ctx->hi++;
+	ctx->hi += size >> 29;
 
-  /* Append length (before padding) */
-  MD5Update (context, bits, 8);
-  /* Store state in digest */
-  Encode (digest, context->state, 16);
+	used = saved_lo & 0x3f;
 
-  /* Zeroize sensitive information. */
-  MD5_memset ((POINTER)context, 0, sizeof (*context));
-}
-
-/* 
- * MD5 basic transformation.
- * Transforms state based on block.
- */
-static void MD5Transform (state, block)
-UINT4 state[4];
-unsigned char block[64];
-{
-  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
-  Decode (x, block, 64);
-
-  /* Round 1 */
-  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /*  1 */
-  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /*  2 */
-  FF (c, d, a, b, x[ 2], S13, 0x242070db); /*  3 */
-  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /*  4 */
-  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /*  5 */
-  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /*  6 */
-  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /*  7 */
-  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /*  8 */
-  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /*  9 */
-  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
-  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
-  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
-  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
-  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
-  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
-  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- /* Round 2 */
-  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
-  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
-  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
-  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
-  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
-  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
-  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
-  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
-  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
-  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
-  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
-  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
-  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
-  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
-  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
-  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
-  /* Round 3 */
-  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
-  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
-  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
-  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
-  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
-  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
-  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
-  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
-  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
-  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
-  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
-  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
-  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
-  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
-  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
-  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
-  /* Round 4 */
-  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
-  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
-  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
-  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
-  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
-  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
-  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
-  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
-  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
-  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
-  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
-  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
-  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
-  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
-  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
-  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
-  state[0] += a;
-  state[1] += b;
-  state[2] += c;
-  state[3] += d;
-
-  /* Zeroize sensitive information. */
-  MD5_memset ((POINTER)x, 0, sizeof (x));
-}
-
-/* 
- * Encodes input (UINT4) into output (unsigned char).
- * Assumes len is a multiple of 4.
- */
-static void Encode (output, input, len)
-unsigned char *output;
-UINT4 *input;
-unsigned int len;
-{
-  unsigned int i, j;
-
-  for (i = 0, j = 0; j < len; i++, j += 4) {
- output[j] = (unsigned char)(input[i] & 0xff);
- output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
- output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
- output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
-  }
-}
+	if (used) {
+		free = 64 - used;
 
-/* 
- * Decodes input (unsigned char) into output (UINT4).
- * Assumes len is a multiple of 4.
- */
-static void Decode (output, input, len)
-UINT4 *output;
-unsigned char *input;
-unsigned int len;
-{
-  unsigned int i, j;
+		if (size < free) {
+			memcpy(&ctx->buffer[used], data, size);
+			return;
+		}
 
-  for (i = 0, j = 0; j < len; i++, j += 4)
- output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
-   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
-}
+		memcpy(&ctx->buffer[used], data, free);
+		(unsigned char *)data += free;
+		size -= free;
+		body(ctx, ctx->buffer, 64);
+	}
 
-/* 
- * Note: Replace "for loop" with standard memcpy if possible.
- */
-static void MD5_memcpy (output, input, len)
-POINTER output;
-POINTER input;
-unsigned int len;
-{
-  unsigned int i;
+	if (size >= 64) {
+		data = body(ctx, data, size & ~(unsigned long)0x3f);
+		size &= 0x3f;
+	}
 
-  for (i = 0; i < len; i++)
- output[i] = input[i];
+	memcpy(ctx->buffer, data, size);
 }
 
-/* 
- * Note: Replace "for loop" with standard memset if possible.
- */
-static void MD5_memset (output, value, len)
-POINTER output;
-int value;
-unsigned int len;
+void MD5_Final(unsigned char *result, MD5_CTX *ctx)
 {
-  unsigned int i;
-
-  for (i = 0; i < len; i++)
- ((char *)output)[i] = (char)value;
+	unsigned long used, free;
+
+	used = ctx->lo & 0x3f;
+
+	ctx->buffer[used++] = 0x80;
+
+	free = 64 - used;
+
+	if (free < 8) {
+		memset(&ctx->buffer[used], 0, free);
+		body(ctx, ctx->buffer, 64);
+		used = 0;
+		free = 64;
+	}
+
+	memset(&ctx->buffer[used], 0, free - 8);
+
+	ctx->lo <<= 3;
+	ctx->buffer[56] = ctx->lo;
+	ctx->buffer[57] = ctx->lo >> 8;
+	ctx->buffer[58] = ctx->lo >> 16;
+	ctx->buffer[59] = ctx->lo >> 24;
+	ctx->buffer[60] = ctx->hi;
+	ctx->buffer[61] = ctx->hi >> 8;
+	ctx->buffer[62] = ctx->hi >> 16;
+	ctx->buffer[63] = ctx->hi >> 24;
+
+	body(ctx, ctx->buffer, 64);
+
+	result[0] = ctx->a;
+	result[1] = ctx->a >> 8;
+	result[2] = ctx->a >> 16;
+	result[3] = ctx->a >> 24;
+	result[4] = ctx->b;
+	result[5] = ctx->b >> 8;
+	result[6] = ctx->b >> 16;
+	result[7] = ctx->b >> 24;
+	result[8] = ctx->c;
+	result[9] = ctx->c >> 8;
+	result[10] = ctx->c >> 16;
+	result[11] = ctx->c >> 24;
+	result[12] = ctx->d;
+	result[13] = ctx->d >> 8;
+	result[14] = ctx->d >> 16;
+	result[15] = ctx->d >> 24;
+
+	memset(ctx, 0, sizeof(ctx));
 }

+ 74 - 74
src/mem.c

@@ -1,75 +1,56 @@
-/* 
+/*
  * mem.c -- handles:
  *   memory allocation and deallocation
  *   keeping track of what memory is being used by whom
- * 
- * dprintf'ized, 15nov1995
- * 
- * $Id: mem.c,v 1.12 2000/01/08 21:23:14 per Exp $
+ *
+ * $Id: mem.c,v 1.17 2002/01/02 03:46:35 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
  */
 
-#define LOG_MISC 32
 #define MEMTBLSIZE 25000	/* yikes! */
+#define COMPILING_MEM
 
-#if HAVE_CONFIG_H
-#  include <config.h>
-#endif
+#include "main.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 
-typedef int (*Function) ();
 #include "mod/modvals.h"
 
-extern module_entry *module_list;
-void fatal(char *, int);
+
+extern module_entry	*module_list;
 
 #ifdef DEBUG_MEM
-unsigned long memused = 0;
-static int lastused = 0;
+unsigned long	memused = 0;
+static int	lastused = 0;
 
 struct {
-  void *ptr;
-  int size;
-  short line;
-  char file[20];
+  void	*ptr;
+  int	 size;
+  short	 line;
+  char	 file[20];
 } memtbl[MEMTBLSIZE];
-
 #endif
 
-#ifdef HAVE_DPRINTF
-#define dprintf dprintf_eggdrop
-#endif
-
-#define DP_HELP         0x7FF4
-
-/* prototypes */
-#if !defined(HAVE_PRE7_5_TCL) && defined(__STDC__)
-void dprintf(int arg1, ...);
-void putlog(int arg1, ...);
-#else
-void dprintf();
-void putlog();
-#endif
+/* Prototypes */
 int expected_memory();
 int expmem_chanprog();
 int expmem_misc();
@@ -79,14 +60,16 @@ int expmem_dccutil();
 int expmem_botnet();
 int expmem_tcl();
 int expmem_tclhash();
+int expmem_tclmisc();
 int expmem_net();
 int expmem_modules();
 int expmem_language();
 int expmem_tcldcc();
-void tell_netdebug();
-void do_module_report(int, int, char *);
+int expmem_dns();
+
 
-/* initialize the memory structure */
+/* Initialize the memory structure
+ */
 void init_mem()
 {
 #ifdef DEBUG_MEM
@@ -97,7 +80,8 @@ void init_mem()
 #endif
 }
 
-/* tell someone the gory memory details */
+/* Tell someone the gory memory details
+ */
 void tell_mem_status(char *nick)
 {
 #ifdef DEBUG_MEM
@@ -119,7 +103,8 @@ void tell_mem_status_dcc(int idx)
 
   exp = expected_memory();	/* in main.c ? */
   per = ((lastused * 1.0) / (MEMTBLSIZE * 1.0)) * 100.0;
-  dprintf(idx, "Memory table: %d/%d (%.1f%% full)\n", lastused, MEMTBLSIZE, per);
+  dprintf(idx, "Memory table: %d/%d (%.1f%% full)\n", lastused, MEMTBLSIZE,
+	  per);
   per = ((exp * 1.0) / (memused * 1.0)) * 100.0;
   if (per != 100.0)
     dprintf(idx, "Memory fault: only accounting for %d/%ld (%.1f%%)\n",
@@ -132,7 +117,7 @@ void tell_mem_status_dcc(int idx)
 void debug_mem_to_dcc(int idx)
 {
 #ifdef DEBUG_MEM
-#define MAX_MEM 11
+#define MAX_MEM 13
   unsigned long exp[MAX_MEM], use[MAX_MEM], l;
   int i, j;
   char fn[20], sofar[81];
@@ -148,8 +133,10 @@ void debug_mem_to_dcc(int idx)
   exp[6] = expmem_botnet();
   exp[7] = expmem_tcl();
   exp[8] = expmem_tclhash();
-  exp[9] = expmem_modules(1);
-  exp[10] = expmem_tcldcc();
+  exp[9] = expmem_tclmisc();
+  exp[10] = expmem_modules(1);
+  exp[11] = expmem_tcldcc();
+  exp[12] = expmem_dns();
   for (me = module_list; me; me = me->next)
     me->mem_work = 0;
   for (i = 0; i < MAX_MEM; i++)
@@ -160,37 +147,38 @@ void debug_mem_to_dcc(int idx)
     if (p)
       *p = 0;
     l = memtbl[i].size;
-    if (!strcasecmp(fn, "language.c"))
+    if (!strcmp(fn, "language.c"))
       use[0] += l;
-    else if (!strcasecmp(fn, "chanprog.c"))
+    else if (!strcmp(fn, "chanprog.c"))
       use[1] += l;
-    else if (!strcasecmp(fn, "misc.c"))
+    else if (!strcmp(fn, "misc.c"))
       use[2] += l;
-    else if (!strcasecmp(fn, "userrec.c"))
+    else if (!strcmp(fn, "userrec.c"))
       use[3] += l;
-    else if (!strcasecmp(fn, "net.c"))
+    else if (!strcmp(fn, "net.c"))
       use[4] += l;
-    else if (!strcasecmp(fn, "dccutil.c"))
+    else if (!strcmp(fn, "dccutil.c"))
       use[5] += l;
-    else if (!strcasecmp(fn, "botnet.c"))
+    else if (!strcmp(fn, "botnet.c"))
       use[6] += l;
-    else if (!strcasecmp(fn, "tcl.c"))
+    else if (!strcmp(fn, "tcl.c"))
       use[7] += l;
-    else if (!strcasecmp(fn, "tclhash.c"))
+    else if (!strcmp(fn, "tclhash.c"))
       use[8] += l;
-    else if (!strcasecmp(fn, "modules.c"))
+    else if (!strcmp(fn, "tclmisc.c"))
       use[9] += l;
-    else if (!strcasecmp(fn, "tcldcc.c"))
+    else if (!strcmp(fn, "modules.c"))
       use[10] += l;
+    else if (!strcmp(fn, "tcldcc.c"))
+      use[11] += l;
+    else if (!strcmp(fn, "dns.c"))
+      use[12] += l;
     else if (p) {
       for (me = module_list; me; me = me->next)
 	if (!strcmp(fn, me->name))
 	  me->mem_work += l;
-    } else {
+    } else
       dprintf(idx, "Not logging file %s!\n", fn);
-    }
-    if (p)
-      *p = ':';
   }
   for (i = 0; i < MAX_MEM; i++) {
     switch (i) {
@@ -222,11 +210,17 @@ void debug_mem_to_dcc(int idx)
       strcpy(fn, "tclhash.c");
       break;
     case 9:
-      strcpy(fn, "modules.c");
+      strcpy(fn, "tclmisc.c");
       break;
     case 10:
+      strcpy(fn, "modules.c");
+      break;
+    case 11:
       strcpy(fn, "tcldcc.c");
       break;
+    case 12:
+      strcpy(fn, "dns.c");
+      break;
     }
     if (use[i] == exp[i]) {
       dprintf(idx, "File '%-10s' accounted for %lu/%lu (ok)\n", fn, exp[i],
@@ -238,7 +232,7 @@ void debug_mem_to_dcc(int idx)
       for (j = 0; j < lastused; j++) {
 	if ((p = strchr(memtbl[j].file, ':')))
 	  *p = 0;
-	if (!strcasecmp(memtbl[j].file, fn)) {
+	if (!egg_strcasecmp(memtbl[j].file, fn)) {
 	  if (p)
 	    sprintf(&sofar[strlen(sofar)], "%-10s/%-4d:(%04d) ",
 		    p + 1, memtbl[j].line, memtbl[j].size);
@@ -278,7 +272,7 @@ void debug_mem_to_dcc(int idx)
 	strcpy(fn, memtbl[j].file);
 	if ((p = strchr(fn, ':')) != NULL) {
 	  *p = 0;
-	  if (!strcasecmp(fn, me->name)) {
+	  if (!egg_strcasecmp(fn, me->name)) {
 	    sprintf(&sofar[strlen(sofar)], "%-10s/%-4d:(%04X) ", p + 1,
 		    memtbl[j].line, memtbl[j].size);
 	    if (strlen(sofar) > 60) {
@@ -303,11 +297,12 @@ void debug_mem_to_dcc(int idx)
   tell_netdebug(idx);
 }
 
-void *n_malloc(int size, char *file, int line)
+void *n_malloc(int size, const char *file, int line)
 {
-  void *x;
+  void	*x;
 #ifdef DEBUG_MEM
-  int i = 0;
+  int	 i = 0;
+  char	*p;
 #endif
 
   x = (void *) malloc(size);
@@ -319,13 +314,14 @@ void *n_malloc(int size, char *file, int line)
 #ifdef DEBUG_MEM
   if (lastused == MEMTBLSIZE) {
     putlog(LOG_MISC, "*", "*** MEMORY TABLE FULL: %s (%d)", file, line);
-    return x;
+    fatal("Memory table full", 0);
   }
   i = lastused;
   memtbl[i].ptr = x;
   memtbl[i].line = line;
   memtbl[i].size = size;
-  strncpy(memtbl[i].file, file, 19);
+  p = strrchr(file, '/');
+  strncpy(memtbl[i].file, p ? p + 1 : file, 19);
   memtbl[i].file[19] = 0;
   memused += size;
   lastused++;
@@ -333,10 +329,13 @@ void *n_malloc(int size, char *file, int line)
   return x;
 }
 
-void *n_realloc(void *ptr, int size, char *file, int line)
+void *n_realloc(void *ptr, int size, const char *file, int line)
 {
   void *x;
   int i = 0;
+#ifdef DEBUG_MEM
+  char *p;
+#endif
 
   /* ptr == NULL is valid. Avoiding duplicate code further down */
   if (!ptr)
@@ -359,14 +358,15 @@ void *n_realloc(void *ptr, int size, char *file, int line)
   memtbl[i].ptr = x;
   memtbl[i].line = line;
   memtbl[i].size = size;
-  strncpy(memtbl[i].file, file, 19);
+  p = strrchr(file, '/');
+  strncpy(memtbl[i].file, p ? p + 1 : file, 19);
   memtbl[i].file[19] = 0;
   memused += size;
 #endif
   return x;
 }
 
-void n_free(void *ptr, char *file, int line)
+void n_free(void *ptr, const char *file, int line)
 {
   int i = 0;
 
@@ -377,7 +377,7 @@ void n_free(void *ptr, char *file, int line)
     return;
   }
 #ifdef DEBUG_MEM
-  /* give tcl builtins an escape mechanism */
+  /* Give tcl builtins an escape mechanism */
   if (line) {
     for (i = 0; (i < lastused) && (memtbl[i].ptr != ptr); i++);
     if (i == lastused) {

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 354 - 293
src/misc.c


+ 97 - 0
src/misc_file.c

@@ -0,0 +1,97 @@
+/*
+ * misc.c -- handles:
+ *   copyfile() movefile()
+ *
+ * $Id: misc_file.c,v 1.6 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 "main.h"
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "stat.h"
+
+
+/* Copy a file from one place to another (possibly erasing old copy).
+ *
+ * returns:  0 if OK
+ *	     1 if can't open original file
+ *	     2 if can't open new file
+ *	     3 if original file isn't normal
+ *	     4 if ran out of disk space
+ */
+int copyfile(char *oldpath, char *newpath)
+{
+  int fi, fo, x;
+  char buf[512];
+  struct stat st;
+
+#ifndef CYGWIN_HACKS
+  fi = open(oldpath, O_RDONLY, 0);
+#else
+  fi = open(oldpath, O_RDONLY | O_BINARY, 0);
+#endif
+  if (fi < 0)
+    return 1;
+  fstat(fi, &st);
+  if (!(st.st_mode & S_IFREG))
+    return 3;
+  fo = creat(newpath, (int) (st.st_mode & 0777));
+  if (fo < 0) {
+    close(fi);
+    return 2;
+  }
+  for (x = 1; x > 0;) {
+    x = read(fi, buf, 512);
+    if (x > 0) {
+      if (write(fo, buf, x) < x) {	/* Couldn't write */
+	close(fo);
+	close(fi);
+	unlink(newpath);
+	return 4;
+      }
+    }
+  }
+#ifdef HAVE_FSYNC
+  fsync(fo);
+#endif /* HAVE_FSYNC */
+  close(fo);
+  close(fi);
+  return 0;
+}
+
+int movefile(char *oldpath, char *newpath)
+{
+  int ret;
+
+#ifdef HAVE_RENAME
+  /* Try to use rename first */
+  if (!rename(oldpath, newpath))
+    return 0;
+#endif /* HAVE_RENAME */
+
+  /* If that fails, fall back to just copying and then
+   * deleting the file.
+   */
+  ret = copyfile(oldpath, newpath);
+  if (!ret)
+    unlink(oldpath);
+  return ret;
+}

+ 31 - 0
src/misc_file.h

@@ -0,0 +1,31 @@
+/*
+ * misc_file.h
+ *   prototypes for misc_file.c
+ *
+ * $Id: misc_file.h,v 1.3 2002/01/02 03:46:36 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_MISC_FILE_H
+#define _EGG_MISC_FILE_H
+
+int copyfile(char *, char *);
+int movefile(char *, char *);
+
+#endif				/* _EGG_MISC_FILE_H */

+ 136 - 44
src/mod/Makefile.in

@@ -1,8 +1,11 @@
 # Makefile for src/mod/
-# $Id: Makefile.in,v 1.7 1999/12/15 02:32:58 guppy Exp $
+# $Id: Makefile.in,v 1.13 2000/12/21 20:20:03 guppy Exp $
 
-SHELL = /bin/sh
+SHELL = @SHELL@
 top_srcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+MOD_UPDIR = @MOD_UPDIR@
 
 @SET_MAKE@
 INSTALL = @INSTALL@
@@ -10,71 +13,160 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 
+CC = @CC@
+LD = @CC@
+STRIP = @STRIP@
+CFLAGS = @CFLAGS@ -I../.. -I$(top_srcdir) @DEFS@ $(CFLGS)
+CPPFLAGS = @CPPFLAGS@
+MOD_CFLAGS = @CFLAGS@ -I. -I../../.. -I$(MOD_UPDIR)$(top_srcdir) \
+  -I$(MOD_UPDIR)$(top_srcdir)/src/mod @DEFS@ $(CFLGS)
+MOD_CPPFLAGS = @CPPFLAGS@
+XLIBS = @XLIBS@
+MOD_EXT = @MOD_EXT@
+
+# Note: The following three lines are automatically adjusted by
+#       misc/modconfig. They have to be present here.
+mods =
+mod_objs =
+mod_libs =
+
+modconfig = $(top_srcdir)/misc/modconfig --bindir=../.. \
+  --top_srcdir=$(top_srcdir)
+egg_ac_parameters = @egg_ac_parameters@
+
 MAKE_MOD = $(MAKE) 'MAKE=$(MAKE)' 'CC=$(CC)' 'LD=$(LD)' \
-'STRIP=$(STRIP)' 'CFLAGS=$(CFLAGS)' 'CPPFLAGS=$(CPPFLAGS)'
+'STRIP=$(STRIP)' 'CFLAGS=$(MOD_CFLAGS)' 'CPPFLAGS=$(MOD_CPPFLAGS)' \
+'XLIBS=$(XLIBS)' 'MOD_EXT=$(MOD_EXT)' 'SHELL=$(SHELL)'
+
 
 doofus:
 	@echo ""
 	@echo "Let's try this from the right directory..."
 	@echo ""
-	@cd $(top_srcdir); $(MAKE)
+	@cd ../.. && $(MAKE)
+
+modules: $(mod_libs)
+	@echo "All modules compiled."
+	@echo ""
+
+static: $(mod_objs)
+	@$(modconfig) static.h
+
+.SUFFIXES:
+.SUFFIXES: .mod .mod_so .mod_o
 
-modules:
-	@for i in *.mod; do cd $$i; $(MAKE_MOD) modules; cd ../; done
+.mod.mod_so:
+	@if test ! -d $*.mod; then mkdir $*.mod; fi; \
+	if test ! -r $*.mod/Makefile; then \
+		cp $(srcdir)/$*.mod/Makefile $*.mod/Makefile; \
+	fi; \
+	cd $*.mod && $(MAKE_MOD) 'VPATH=$(MOD_UPDIR)$(srcdir)/$*.mod' 'srcdir=$(MOD_UPDIR)$(srcdir)/$*.mod' 'MAKE=$(MAKE)' modules;
 
-static:
-	@./buildstatic
-	@for i in *.mod; do cd $$i; $(MAKE_MOD) static; cd ../; done
+.mod.mod_o:
+	@if test ! -d $*.mod; then mkdir $*.mod; fi; \
+	if test ! -r $*.mod/Makefile; then \
+		cp $(srcdir)/$*.mod/Makefile $*.mod/Makefile; \
+	fi; \
+	cd $*.mod && $(MAKE_MOD) 'VPATH=$(MOD_UPDIR)$(srcdir)/$*.mod' 'srcdir=$(MOD_UPDIR)$(srcdir)/$*.mod' 'MAKE=$(MAKE)' static;
 
 depend:
-	@for i in *.mod; do cd $$i; $(MAKE_MOD) depend; cd ../; done
+	@for i in $(mods); do \
+		if test ! -d $$i; then mkdir $$i; fi; \
+		if test ! -r $$i/Makefile; then \
+			cp $(srcdir)/$$i/Makefile $$i/Makefile; \
+		fi; \
+		(cd $$i && $(MAKE_MOD) "VPATH=$(MOD_UPDIR)$(srcdir)/$$i" "srcdir=$(MOD_UPDIR)$(srcdir)/$$i" depend); \
+	done
+
+config:
+	@for i in $(mods); do \
+		if test -f $(srcdir)/$$i/configure; then \
+			modname=`echo $$i | sed -e 's/.mod//'`; \
+			echo ""; \
+			echo "Configuring module $${modname} ..."; \
+			echo ""; \
+			if test ! -d $$i; then mkdir $$i; fi; \
+			(cd $$i && $(MOD_UPDIR)$(srcdir)/$$i/configure $(egg_ac_parameters) --cache-file=../../../config.cache --srcdir=$(MOD_UPDIR)$(top_srcdir)/src/mod/$$i); \
+		fi; \
+	done; \
+	echo ""
 
 clean:
-	@rm -f *.o *.so *~ static.h
-	@for i in *.mod; do cd $$i; $(MAKE) 'MAKE=$(MAKE)' clean; cd ../; done
+	@rm -f *.o *.$(MOD_EXT) *~ static.h mod.xlibs
+	@for i in *.mod; do \
+		if test ! -d $$i; then mkdir $$i; fi; \
+		if (test ! -r $$i/Makefile) && \
+		   (test -r $(srcdir)/$$i/Makefile); then \
+			cp $(srcdir)/$$i/Makefile $$i/Makefile; \
+		fi; \
+		if (test -r $$i/Makefile); then \
+			(cd $$i; $(MAKE) "VPATH=$(MOD_UPDIR)$(srcdir)/$$i" "srcdir=$(MOD_UPDIR)$(srcdir)/$$i" 'MAKE=$(MAKE)' clean); \
+		fi; \
+	done
+
+distclean:
+	@rm -f *.o *.$(MOD_EXT) *~ static.h mod.xlibs
+	@for i in *.mod; do \
+		if test ! -d $$i; then mkdir $$i; fi; \
+		if (test ! -r $$i/Makefile) && \
+		   (test -r $(srcdir)/$$i/Makefile); then \
+			cp $(srcdir)/$$i/Makefile $$i/Makefile; \
+		fi; \
+		if (test -r $$i/Makefile); then \
+			(cd $$i; $(MAKE) "VPATH=$(MOD_UPDIR)$(srcdir)/$$i" "srcdir=$(MOD_UPDIR)$(srcdir)/$$i" 'MAKE=$(MAKE)' distclean); \
+		fi; \
+	done
 
 install: install-help install-language
 
 install-help:
 	@echo "Copying module help files."
-	@if test ! "x`echo *.mod/help/*.help`" = "x*.mod/help/*.help"; then \
-		if test ! -d $(DEST)/help; then \
-			echo "Creating 'help' subdirectory."; \
-			$(top_srcdir)/mkinstalldirs $(DEST)/help; \
+	@if test ! -d $(DEST)/help; then \
+		echo "Creating 'help' subdirectory."; \
+		$(top_srcdir)/misc/mkinstalldirs $(DEST)/help; \
+	fi; \
+	for i in $(mods); do \
+		if test ! "x`echo $(srcdir)/$$i/help/*.help`" = "x$(srcdir)/$$i/help/*.help"; then \
+			for h in $(srcdir)/$$i/help/*.help; do \
+				$(INSTALL_DATA) $$h $(DEST)/help/; \
+			done; \
 		fi; \
-		for i in *.mod/help/*.help; do \
-			$(INSTALL_DATA) $$i $(DEST)/help/; \
-		done; \
-	fi
-	@if test ! "x`echo *.mod/help/msg/*.help`" = "x*.mod/help/msg/*.help"; then \
-		if test ! -d $(DEST)/help/msg; then \
-			echo "Creating 'help/msg' subdirectory."; \
-			$(top_srcdir)/mkinstalldirs $(DEST)/help/msg; \
+	done;
+	@if test ! -d $(DEST)/help/msg; then \
+		echo "Creating 'help/msg' subdirectory."; \
+		$(top_srcdir)/misc/mkinstalldirs $(DEST)/help/msg; \
+	fi; \
+	for i in $(mods); do \
+		if test ! "x`echo $(srcdir)/$$i/help/msg/*.help`" = "x$(srcdir)/$$i/help/msg/*.help"; then \
+			for h in $(srcdir)/$$i/help/msg/*.help; do \
+				$(INSTALL_DATA) $$h $(DEST)/help/msg/; \
+			done; \
 		fi; \
-		for i in *.mod/help/msg/*.help; do \
-			$(INSTALL_DATA) $$i $(DEST)/help/msg/; \
-		done; \
-	fi
-	@if test ! "x`echo *.mod/help/set/*.help`" = "x*.mod/help/set/*.help"; then \
-		if test ! -d $(DEST)/help/set; then \
-			echo "Creating 'help/set' subdirectory."; \
-			$(top_srcdir)/mkinstalldirs $(DEST)/help/set; \
+	done;
+	@if test ! -d $(DEST)/help/set; then \
+		echo "Creating 'help/set' subdirectory."; \
+		$(top_srcdir)/misc/mkinstalldirs $(DEST)/help/set; \
+	fi; \
+	for i in $(mods); do \
+		if test ! "x`echo $(srcdir)/$$i/help/set/*.help`" = "x$(srcdir)/$$i/help/set/*.help"; then \
+			for h in $(srcdir)/$$i/help/set/*.help; do \
+				$(INSTALL_DATA) $$h $(DEST)/help/set/; \
+			done; \
 		fi; \
-		for i in *.mod/help/set/*.help; do \
-			$(INSTALL_DATA) $$i $(DEST)/help/set/; \
-		done; \
-	fi
+	done;
 
 install-language:
 	@echo "Copying module language files."
-	@if test ! "x`echo *.mod/language/*.lang`" = "x*.mod/language/*.lang"; then \
-		if test ! -d $(DEST)/language; then \
-			echo "Creating 'language' subdirectory."; \
-			$(top_srcdir)/mkinstalldirs $(DEST)/language; \
+	@if test ! -d $(DEST)/language; then \
+		echo "Creating 'language' subdirectory."; \
+		$(top_srcdir)/misc/mkinstalldirs $(DEST)/language; \
+	fi; \
+	for i in $(mods); do \
+		if test ! "x`echo $(srcdir)/$$i/language/*.lang`" = "x$(srcdir)/$$i/language/*.lang"; then \
+			for h in $(srcdir)/$$i/language/*.lang; do \
+				$(INSTALL_DATA) $$h $(DEST)/language/; \
+			done; \
 		fi; \
-		for i in *.mod/language/*.lang; do \
-			$(INSTALL_DATA) $$i $(DEST)/language/; \
-		done; \
-	fi
+	done;
 
 #safety hash

+ 25 - 15
src/mod/blowfish.mod/Makefile

@@ -1,34 +1,44 @@
 # Makefile for src/mod/blowfish.mod/
-# $Id: Makefile,v 1.10 1999/12/15 02:32:59 guppy Exp $
+# $Id: Makefile,v 1.11 2000/09/12 15:26:51 fabian Exp $
+
+srcdir = .
+
 
 doofus:
 	@echo ""
 	@echo "Let's try this from the right directory..."
 	@echo ""
-	@cd ../../../; make
+	@cd ../../../ && make
 
 static: ../blowfish.o
 
-modules: ../../../blowfish.so
+modules: ../../../blowfish.$(MOD_EXT)
 
 ../blowfish.o:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c blowfish.c
-	rm -f ../blowfish.o
+	$(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c $(srcdir)/blowfish.c
+	@rm -f ../blowfish.o
 	mv blowfish.o ../
 
-../../../blowfish.so: ../blowfish.o
-	$(LD) -o ../../../blowfish.so ../blowfish.o
-	$(STRIP) ../../../blowfish.so
+../../../blowfish.$(MOD_EXT): ../blowfish.o
+	$(LD) -o ../../../blowfish.$(MOD_EXT) ../blowfish.o $(XLIBS)
+	$(STRIP) ../../../blowfish.$(MOD_EXT)
 
 depend:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -MM *.c > .depend
+	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/blowfish.c > .depend
 
 clean:
-	@rm -f .depend *.o *.so *~
+	@rm -f .depend *.o *.$(MOD_EXT) *~
+distclean: clean
 
 #safety hash
-../blowfish.o: blowfish.c ../module.h ../../../config.h ../../main.h \
- ../../lang.h ../../eggdrop.h ../../flags.h ../../proto.h \
- ../../../lush.h ../../cmdt.h ../../tclegg.h ../../tclhash.h \
- ../../chan.h ../../users.h ../modvals.h ../../tandem.h blowfish.h \
- bf_tab.h
+../blowfish.o: .././blowfish.mod/blowfish.c ../../../src/mod/module.h \
+ ../../../src/main.h ../../../config.h ../../../src/lang.h \
+ ../../../src/eggdrop.h ../../../src/flags.h ../../../src/proto.h \
+ ../../../lush.h ../../../src/misc_file.h ../../../src/cmdt.h \
+ ../../../src/tclegg.h ../../../src/tclhash.h ../../../src/chan.h \
+ ../../../src/users.h ../../../src/compat/compat.h \
+ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \
+ ../../../src/compat/memset.h ../../../src/compat/memcpy.h \
+ ../../../src/compat/strcasecmp.h ../../../src/compat/strftime.h \
+ ../../../src/mod/modvals.h ../../../src/tandem.h \
+ ../blowfish.mod/blowfish.h ../blowfish.mod/bf_tab.h

+ 22 - 5
src/mod/blowfish.mod/bf_tab.h

@@ -1,14 +1,31 @@
-/* 
+/*
  * bf_tab.h -- part of blowfish.mod
  *   Blowfish P-box and S-box tables
- * 
- * $Id: bf_tab.h,v 1.3 1999/12/22 20:30:03 guppy Exp $
+ *
+ * $Id: bf_tab.h,v 1.5 2002/01/02 03:46:37 guppy Exp $
+ */
+/*
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_MOD_BLOWFISH_BF_TAB_H
 #define _EGG_MOD_BLOWFISH_BF_TAB_H
 
-static UWORD_32bits initbf_P[bf_N + 2] =
+static u_32bit_t initbf_P[bf_N + 2] =
 {
   0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
   0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
@@ -16,7 +33,7 @@ static UWORD_32bits initbf_P[bf_N + 2] =
   0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
   0x9216d5d9, 0x8979fb1b,
 };
-static UWORD_32bits initbf_S[4][256] =
+static u_32bit_t initbf_S[4][256] =
 {
   {
     0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,

+ 97 - 71
src/mod/blowfish.mod/blowfish.c

@@ -1,24 +1,41 @@
-/* 
+/*
  * blowfish.c -- part of blowfish.mod
  *   encryption and decryption of passwords
- * 
- * $Id: blowfish.c,v 1.9 2000/01/06 21:03:46 guppy Exp $
+ *
+ * $Id: blowfish.c,v 1.23 2002/06/06 18:52:22 wcc Exp $
  */
-/* 
- * The first half of this is very lightly edited from public domain
- * sourcecode.  For simplicity, this entire module will remain public
- * domain.
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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.
+ */
+/*
+ * This code was originally in the public domain.
  */
 
 #define MODULE_NAME "encryption"
-#define MAKING_BLOWFISH
-#include "../module.h"
+#define MAKING_ENCRYPTION
+
+#include "src/mod/module.h"
 #include "blowfish.h"
 #include "bf_tab.h"		/* P-box P-array, S-box */
 #undef global
 static Function *global = NULL;
 
-/* each box takes up 4k so be very careful here */
+/* Each box takes up 4k so be very careful here */
 #define BOXES 3
 
 /* #define S(x,i) (bf_S[i][x.w.byte##i]) */
@@ -29,35 +46,34 @@ static Function *global = NULL;
 #define bf_F(x) (((S0(x) + S1(x)) ^ S2(x)) + S3(x))
 #define ROUND(a,b,n) (a.word ^= bf_F(b) ^ bf_P[n])
 
-/* keep a set of rotating P & S boxes */
+/* Keep a set of rotating P & S boxes */
 static struct box_t {
-  UWORD_32bits *P;
-  UWORD_32bits **S;
+  u_32bit_t *P;
+  u_32bit_t **S;
   char key[81];
   char keybytes;
   time_t lastuse;
 } box[BOXES];
 
-/* static UWORD_32bits bf_P[bf_N+2]; */
-/* static UWORD_32bits bf_S[4][256]; */
-static UWORD_32bits *bf_P;
-static UWORD_32bits **bf_S;
+/* static u_32bit_t bf_P[bf_N+2]; */
+/* static u_32bit_t bf_S[4][256]; */
+static u_32bit_t *bf_P;
+static u_32bit_t **bf_S;
 
 static int blowfish_expmem()
 {
   int i, tot = 0;
 
-  Context;
   for (i = 0; i < BOXES; i++)
     if (box[i].P != NULL) {
-      tot += ((bf_N + 2) * sizeof(UWORD_32bits));
-      tot += (4 * sizeof(UWORD_32bits *));
-      tot += (4 * 256 * sizeof(UWORD_32bits));
+      tot += ((bf_N + 2) * sizeof(u_32bit_t));
+      tot += (4 * sizeof(u_32bit_t *));
+      tot += (4 * 256 * sizeof(u_32bit_t));
     }
   return tot;
 }
 
-static void blowfish_encipher(UWORD_32bits * xl, UWORD_32bits * xr)
+static void blowfish_encipher(u_32bit_t * xl, u_32bit_t * xr)
 {
   union aword Xl;
   union aword Xr;
@@ -88,7 +104,7 @@ static void blowfish_encipher(UWORD_32bits * xl, UWORD_32bits * xr)
   *xl = Xr.word;
 }
 
-static void blowfish_decipher(UWORD_32bits * xl, UWORD_32bits * xr)
+static void blowfish_decipher(u_32bit_t * xl, u_32bit_t * xr)
 {
   union aword Xl;
   union aword Xr;
@@ -138,35 +154,35 @@ static void blowfish_report(int idx, int details)
   }
 }
 
-static void blowfish_init(UBYTE_08bits * key, int keybytes)
+static void blowfish_init(u_8bit_t * key, int keybytes)
 {
   int i, j, bx;
   time_t lowest;
-  UWORD_32bits data;
-  UWORD_32bits datal;
-  UWORD_32bits datar;
+  u_32bit_t data;
+  u_32bit_t datal;
+  u_32bit_t datar;
   union aword temp;
 
-  /* drummer: fixes crash if key is longer than 80 char */
+  /* drummer: Fixes crash if key is longer than 80 char. This may cause the key
+   *          to not end with \00 but that's no problem.
+   */
   if (keybytes > 80)
     keybytes = 80;
-  /* this may cause key wont end with \00 but it isnt problem */
-  /* strNcpy(), strNcmp()... */
 
-  /* is buffer already allocated for this? */
+  /* Is buffer already allocated for this? */
   for (i = 0; i < BOXES; i++)
     if (box[i].P != NULL) {
       if ((box[i].keybytes == keybytes) &&
 	  (!strncmp((char *) (box[i].key), (char *) key, keybytes))) {
-	/* match! */
+	/* Match! */
 	box[i].lastuse = now;
 	bf_P = box[i].P;
 	bf_S = box[i].S;
 	return;
       }
     }
-  /* no pre-allocated buffer: make new one */
-  /* set 'bx' to empty buffer */
+  /* No pre-allocated buffer: make new one */
+  /* Set 'bx' to empty buffer */
   bx = (-1);
   for (i = 0; i < BOXES; i++) {
     if (box[i].P == NULL) {
@@ -175,7 +191,7 @@ static void blowfish_init(UBYTE_08bits * key, int keybytes)
     }
   }
   if (bx < 0) {
-    /* find oldest */
+    /* Find oldest */
     lowest = now;
     for (i = 0; i < BOXES; i++)
       if (box[i].lastuse <= lowest) {
@@ -187,21 +203,22 @@ static void blowfish_init(UBYTE_08bits * key, int keybytes)
       nfree(box[bx].S[i]);
     nfree(box[bx].S);
   }
-  /* initialize new buffer */
+  /* Initialize new buffer */
   /* uh... this is over 4k */
-  box[bx].P = (UWORD_32bits *) nmalloc((bf_N + 2) * sizeof(UWORD_32bits));
-  box[bx].S = (UWORD_32bits **) nmalloc(4 * sizeof(UWORD_32bits *));
+  box[bx].P = (u_32bit_t *) nmalloc((bf_N + 2) * sizeof(u_32bit_t));
+  box[bx].S = (u_32bit_t **) nmalloc(4 * sizeof(u_32bit_t *));
   for (i = 0; i < 4; i++)
-    box[bx].S[i] = (UWORD_32bits *) nmalloc(256 * sizeof(UWORD_32bits));
+    box[bx].S[i] = (u_32bit_t *) nmalloc(256 * sizeof(u_32bit_t));
   bf_P = box[bx].P;
   bf_S = box[bx].S;
   box[bx].keybytes = keybytes;
   strncpy(box[bx].key, key, keybytes);
   box[bx].key[keybytes] = 0;
   box[bx].lastuse = now;
-  /* robey: reset blowfish boxes to initial state */
-  /* (i guess normally it just keeps scrambling them, but here it's
-   * important to get the same encrypted result each time) */
+  /* Robey: Reset blowfish boxes to initial state
+   * (I guess normally it just keeps scrambling them, but here it's
+   * important to get the same encrypted result each time)
+   */
   for (i = 0; i < bf_N + 2; i++)
     bf_P[i] = initbf_P[i];
   for (i = 0; i < 4; i++)
@@ -237,14 +254,13 @@ static void blowfish_init(UBYTE_08bits * key, int keybytes)
   }
 }
 
-/* stuff below this line was written by robey for eggdrop use */
-
-/* of course, if you change either of these, then your userfile will
- * no longer be able to be shared. :) */
+/* Of course, if you change either of these, then your userfile will
+ * no longer be able to be shared. :)
+ */
 #define SALT1  0xdeadd061
 #define SALT2  0x23f6b095
 
-/* convert 64-bit encrypted password to text for userfile */
+/* Convert 64-bit encrypted password to text for userfile */
 static char *base64 = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
 static int base64dec(char c)
@@ -259,11 +275,11 @@ static int base64dec(char c)
 
 static void blowfish_encrypt_pass(char *text, char *new)
 {
-  UWORD_32bits left, right;
+  u_32bit_t left, right;
   int n;
   char *p;
 
-  blowfish_init(text, strlen(text));
+  blowfish_init((unsigned char *) text, strlen(text));
   left = SALT1;
   right = SALT2;
   blowfish_encipher(&left, &right);
@@ -284,14 +300,16 @@ static void blowfish_encrypt_pass(char *text, char *new)
   *p = 0;
 }
 
-/* returned string must be freed when done with it! */
+/* Returned string must be freed when done with it!
+ */
 static char *encrypt_string(char *key, char *str)
 {
-  UWORD_32bits left, right;
-  char *p, *s, *dest, *d;
+  u_32bit_t left, right;
+  unsigned char *p;
+  char *s, *dest, *d;
   int i;
 
-  /* pad fake string with 8 bytes to make sure there's enough */
+  /* Pad fake string with 8 bytes to make sure there's enough */
   s = (char *) nmalloc(strlen(str) + 9);
   strcpy(s, str);
   if ((!key) || (!key[0]))
@@ -302,7 +320,7 @@ static char *encrypt_string(char *key, char *str)
     p++;
   for (i = 0; i < 8; i++)
     *p++ = 0;
-  blowfish_init(key, strlen(key));
+  blowfish_init((unsigned char *) key, strlen(key));
   p = s;
   d = dest;
   while (*p) {
@@ -329,14 +347,15 @@ static char *encrypt_string(char *key, char *str)
   return dest;
 }
 
-/* returned string must be freed when done with it! */
+/* Returned string must be freed when done with it!
+ */
 static char *decrypt_string(char *key, char *str)
 {
-  UWORD_32bits left, right;
+  u_32bit_t left, right;
   char *p, *s, *dest, *d;
   int i;
 
-  /* pad encoded string with 0 bits in case it's bogus */
+  /* Pad encoded string with 0 bits in case it's bogus */
   s = (char *) nmalloc(strlen(str) + 12);
   strcpy(s, str);
   if ((!key) || (!key[0]))
@@ -347,7 +366,7 @@ static char *decrypt_string(char *key, char *str)
     p++;
   for (i = 0; i < 12; i++)
     *p++ = 0;
-  blowfish_init(key, strlen(key));
+  blowfish_init((unsigned char *) key, strlen(key));
   p = s;
   d = dest;
   while (*p) {
@@ -404,19 +423,18 @@ static int tcl_encpass STDVAR
 
 static tcl_cmds mytcls[] =
 {
-  {"encrypt", tcl_encrypt},
-  {"decrypt", tcl_decrypt},
-  {"encpass", tcl_encpass},
-  {0, 0}
+  {"encrypt",	tcl_encrypt},
+  {"decrypt",	tcl_decrypt},
+  {"encpass",	tcl_encpass},
+  {NULL,	NULL}
 };
 
-/* you CANT -module an encryption module , so -module just resets it */
 static char *blowfish_close()
 {
-  return "You can't unload an encryption module";
+  return "You can't unload the encryption module";
 }
 
-char *blowfish_start(Function *);
+EXPORT_SCOPE char *blowfish_start(Function *);
 
 static Function blowfish_table[] =
 {
@@ -430,27 +448,35 @@ static Function blowfish_table[] =
   (Function) decrypt_string,
 };
 
-/* initialize buffered boxes */
-char *blowfish_start(Function * global_funcs)
+char *blowfish_start(Function *global_funcs)
 {
   int i;
 
+  /* `global_funcs' is NULL if eggdrop is recovering from a restart.
+   *
+   * As the encryption module is never unloaded, only initialise stuff
+   * that got reset during restart, e.g. the tcl bindings.
+   */
   if (global_funcs) {
     global = global_funcs;
 
     if (!module_rename("blowfish", MODULE_NAME))
       return "Already loaded.";
+    /* Initialize buffered boxes */
     for (i = 0; i < BOXES; i++) {
       box[i].P = NULL;
       box[i].S = NULL;
       box[i].key[0] = 0;
       box[i].lastuse = 0L;
     }
-    Context;
-    module_register(MODULE_NAME, blowfish_table, 2, 0);
-    if (!module_depend(MODULE_NAME, "eggdrop", 104, 0))
-      return "This module requires eggdrop1.4.0 or later";
+    module_register(MODULE_NAME, blowfish_table, 2, 1);
+    if (!module_depend(MODULE_NAME, "eggdrop", 106, 3)) {
+      module_undepend(MODULE_NAME);
+      return "This module requires Eggdrop 1.6.3 or later.";
+    }
     add_hook(HOOK_ENCRYPT_PASS, (Function) blowfish_encrypt_pass);
+    add_hook(HOOK_ENCRYPT_STRING, (Function) encrypt_string);
+    add_hook(HOOK_DECRYPT_STRING, (Function) decrypt_string);
   }
   add_tcl_commands(mytcls);
   return NULL;

+ 31 - 40
src/mod/blowfish.mod/blowfish.h

@@ -1,61 +1,52 @@
-/* 
+/*
  * blowfish.h -- part of blowfish.mod
- * 
- * modified 19jul1996 by robey -- uses autoconf values now
- * 
- * $Id: blowfish.h,v 1.4 1999/12/22 20:30:03 guppy Exp $
+ *
+ * $Id: blowfish.h,v 1.7 2002/01/02 03:46:37 guppy Exp $
+ */
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_MOD_BLOWFISH_BLOWFISH_H
 #define _EGG_MOD_BLOWFISH_BLOWFISH_H
 
-#define MAXKEYBYTES 56		/* 448 bits */
-#define bf_N             16
-#define noErr            0
-#define DATAERROR        -1
-#define KEYBYTES         8
-
-#define UBYTE_08bits  char
-#define UWORD_16bits  unsigned short
-
-#if SIZEOF_INT==4
-#define UWORD_32bits  unsigned int
-#else
-#if SIZEOF_LONG==4
-#define UWORD_32bits  unsigned long
-#endif
-#endif
-
-/* choose a byte order for your hardware */
+#define MAXKEYBYTES	56		/* 448 bits */
+#define bf_N		16
+#define noErr		 0
+#define DATAERROR	-1
+#define KEYBYTES	 8
 
-#ifdef WORDS_BIGENDIAN
-/* ABCD - big endian - motorola */
 union aword {
-  UWORD_32bits word;
-  UBYTE_08bits byte[4];
+  u_32bit_t word;
+  u_8bit_t byte[4];
   struct {
+#ifdef WORDS_BIGENDIAN
     unsigned int byte0:8;
     unsigned int byte1:8;
     unsigned int byte2:8;
     unsigned int byte3:8;
-  } w;
-};
-
-#endif				/* WORDS_BIGENDIAN */
-
-#ifndef WORDS_BIGENDIAN
-/* DCBA - little endian - intel */
-union aword {
-  UWORD_32bits word;
-  UBYTE_08bits byte[4];
-  struct {
+#else				/* !WORDS_BIGENDIAN */
     unsigned int byte3:8;
     unsigned int byte2:8;
     unsigned int byte1:8;
     unsigned int byte0:8;
+#endif				/* !WORDS_BIGENDIAN */
   } w;
 };
 
-#endif				/* !WORDS_BIGENDIAN */
-
 #endif				/* _EGG_MOD_BLOWFISH_BLOWFISH_H */

+ 0 - 24
src/mod/buildstatic

@@ -1,24 +0,0 @@
-#! /bin/sh
-# $Id: buildstatic,v 1.4 1999/12/15 02:32:58 guppy Exp $
-
-rm -f static.h
-for i in *.mod
-do
-y=`echo $i | sed s/.mod//`
-cat >> static.h << EOF
-char *${y}_start();
-EOF
-done
-cat >> static.h << EOF
-static void link_statics() {
-EOF
-for i in *.mod
-do
-y=`echo $i | sed s/.mod//`
-cat >> static.h << EOF
-  check_static("${y}", ${y}_start);
-EOF
-done
-cat >> static.h << EOF
-}
-EOF

+ 27 - 15
src/mod/channels.mod/Makefile

@@ -1,34 +1,46 @@
 # Makefile for src/mod/channels.mod/
-# $Id: Makefile,v 1.10 1999/12/15 02:32:59 guppy Exp $
+# $Id: Makefile,v 1.12 2000/09/12 15:26:52 fabian Exp $
+
+srcdir = .
+
 
 doofus:
 	@echo ""
 	@echo "Let's try this from the right directory..."
 	@echo ""
-	@cd ../../../; make
+	@cd ../../../ && make
 
 static: ../channels.o
 
-modules: ../../../channels.so
+modules: ../../../channels.$(MOD_EXT)
 
 ../channels.o:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c channels.c
-	rm -f ../channels.o
+	$(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c $(srcdir)/channels.c
+	@rm -f ../channels.o
 	mv channels.o ../
 
-../../../channels.so: ../channels.o
-	$(LD) -o ../../../channels.so ../channels.o
-	$(STRIP) ../../../channels.so
+../../../channels.$(MOD_EXT): ../channels.o
+	$(LD) -o ../../../channels.$(MOD_EXT) ../channels.o $(XLIBS)
+	$(STRIP) ../../../channels.$(MOD_EXT)
 
 depend:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -MM *.c > .depend
+	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/channels.c > .depend
 
 clean:
-	@rm -f .depend *.o *.so *~
+	@rm -f .depend *.o *.$(MOD_EXT) *~
+distclean: clean
 
 #safety hash
-../channels.o: channels.c ../module.h ../../../config.h ../../main.h \
- ../../lang.h ../../eggdrop.h ../../flags.h ../../proto.h \
- ../../../lush.h ../../cmdt.h ../../tclegg.h ../../tclhash.h \
- ../../chan.h ../../users.h ../modvals.h ../../tandem.h channels.h \
- cmdschan.c tclchan.c userchan.c
+../channels.o: .././channels.mod/channels.c ../../../src/mod/module.h \
+ ../../../src/main.h ../../../config.h ../../../src/lang.h \
+ ../../../src/eggdrop.h ../../../src/flags.h ../../../src/proto.h \
+ ../../../lush.h ../../../src/misc_file.h ../../../src/cmdt.h \
+ ../../../src/tclegg.h ../../../src/tclhash.h ../../../src/chan.h \
+ ../../../src/users.h ../../../src/compat/compat.h \
+ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \
+ ../../../src/compat/memset.h ../../../src/compat/memcpy.h \
+ ../../../src/compat/strcasecmp.h ../../../src/compat/strftime.h \
+ ../../../src/mod/modvals.h ../../../src/tandem.h \
+ ../channels.mod/channels.h ../channels.mod/cmdschan.c \
+ ../channels.mod/tclchan.c ../channels.mod/userchan.c \
+ ../channels.mod/udefchan.c

+ 335 - 195
src/mod/channels.mod/channels.c

@@ -1,23 +1,23 @@
-/* 
+/*
  * channels.c -- part of channels.mod
  *   support for channels within the bot
- * 
- * $Id: channels.c,v 1.34 2000/01/08 21:23:15 per Exp $
+ *
+ * $Id: channels.c,v 1.67 2002/07/18 19:01:44 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -25,32 +25,33 @@
 
 #define MODULE_NAME "channels"
 #define MAKING_CHANNELS
-#include "../module.h"
 #include <sys/stat.h>
-
-static int setstatic = 0;
-static int use_info = 1;
-static int ban_time = 60;
-static int exempt_time = 0;	/* if exempt_time = 0, never remove them */
-static int invite_time = 0;	/* if invite_time = 0, never remove them */
-static char chanfile[121] = "chanfile";
-static Function *global = NULL;
-static int chan_hack = 0;
-static int must_be_owner = 0;
-static int quiet_save = 0;
-
-/* global channel settings (drummer/dw) */
-static char glob_chanset[512] = "\
--clearbans -enforcebans +dynamicbans +userbans -autoop -bitch +greet \
-+protectops +statuslog +stopnethack -revenge -secret -autovoice +cycle \
-+dontkickops -wasoptest -inactive -protectfriends +shared -seen \
-+userexempts +dynamicexempts +userinvites +dynamicinvites -revengebot ";
-/* DO NOT remove the extra space at the end of the string! */
-
-/* default chanmode (drummer,990731) */
-static char glob_chanmode[64] = "nt";
-
-/* global flood settings */
+#include "src/mod/module.h"
+
+static Function *global		= NULL;
+
+static int  setstatic;
+static int  use_info;
+static int  ban_time;
+static int  exempt_time;		/* If exempt_time = 0, never remove
+					   them */
+static int  invite_time;		/* If invite_time = 0, never remove
+					   them */
+static char chanfile[121];
+static int  chan_hack;
+static int  quiet_save;
+static char glob_chanmode[64];		/* Default chanmode (drummer,990731) */
+static struct udef_struct *udef;
+static int global_stopnethack_mode;
+static int global_revenge_mode;
+static int global_idle_kick;		/* Default idle-kick setting. */
+static int global_aop_min;
+static int global_aop_max;
+
+/* Global channel settings (drummer/dw) */
+static char glob_chanset[512];
+
+/* Global flood settings */
 static int gfld_chan_thr;
 static int gfld_chan_time;
 static int gfld_deop_thr;
@@ -61,15 +62,17 @@ static int gfld_join_thr;
 static int gfld_join_time;
 static int gfld_ctcp_thr;
 static int gfld_ctcp_time;
-
-static void remove_channel(struct chanset_t *);
+static int gfld_nick_thr;
+static int gfld_nick_time;
 
 #include "channels.h"
 #include "cmdschan.c"
 #include "tclchan.c"
 #include "userchan.c"
+#include "udefchan.c"
+
 
-void *channel_malloc(int size, char *file, int line)
+static void *channel_malloc(int size, char *file, int line)
 {
   char *p;
 
@@ -78,7 +81,7 @@ void *channel_malloc(int size, char *file, int line)
 #else
   p = nmalloc(size);
 #endif
-  bzero(p, size);
+  egg_bzero(p, size);
   return p;
 }
 
@@ -87,9 +90,9 @@ static void set_mode_protect(struct chanset_t *chan, char *set)
   int i, pos = 1;
   char *s, *s1;
 
-  /* clear old modes */
+  /* Clear old modes */
   chan->mode_mns_prot = chan->mode_pls_prot = 0;
-  chan->limit_prot = (-1);
+  chan->limit_prot = 0;
   chan->key_prot[0] = 0;
   for (s = newsplit(&set); *s; s++) {
     i = 0;
@@ -112,6 +115,21 @@ static void set_mode_protect(struct chanset_t *chan, char *set)
     case 'm':
       i = CHANMODER;
       break;
+    case 'c':
+      i = CHANNOCLR;
+      break;
+    case 'C':
+      i = CHANNOCTCP;
+      break;
+    case 'R':
+      i = CHANREGON;
+      break;
+    case 'M':
+      i = CHANMODR;
+      break;
+    case 'r':
+      i = CHANLONLY;
+      break;
     case 't':
       i = CHANTOPIC;
       break;
@@ -126,7 +144,7 @@ static void set_mode_protect(struct chanset_t *chan, char *set)
       break;
     case 'l':
       i = CHANLIMIT;
-      chan->limit_prot = (-1);
+      chan->limit_prot = 0;
       if (pos) {
 	s1 = newsplit(&set);
 	if (s1[0])
@@ -153,7 +171,7 @@ static void set_mode_protect(struct chanset_t *chan, char *set)
       }
     }
   }
-  /* drummer: +s-p +p-s flood fixed. */
+  /* Prevents a +s-p +p-s flood  (fixed by drummer) */
   if (chan->mode_pls_prot & CHANSEC)
     chan->mode_pls_prot &= ~CHANPRIV;
 }
@@ -168,9 +186,9 @@ static void get_mode_protect(struct chanset_t *chan, char *s)
     ok = 0;
     if (i == 0) {
       tst = chan->mode_pls_prot;
-      if ((tst) || (chan->limit_prot != (-1)) || (chan->key_prot[0]))
+      if ((tst) || (chan->limit_prot != 0) || (chan->key_prot[0]))
 	*p++ = '+';
-      if (chan->limit_prot != (-1)) {
+      if (chan->limit_prot != 0) {
 	*p++ = 'l';
 	sprintf(&s1[strlen(s1)], "%d ", chan->limit_prot);
       }
@@ -195,6 +213,16 @@ static void get_mode_protect(struct chanset_t *chan, char *s)
       *p++ = 's';
     if (tst & CHANMODER)
       *p++ = 'm';
+    if (tst & CHANNOCLR)
+      *p++ = 'c';
+    if (tst & CHANNOCTCP)
+      *p++ = 'C';
+    if (tst & CHANREGON)
+      *p++ = 'R';
+    if (tst & CHANMODR)
+      *p++ = 'M';
+    if (tst & CHANLONLY)
+      *p++ = 'r';
     if (tst & CHANTOPIC)
       *p++ = 't';
     if (tst & CHANNOMSG)
@@ -212,55 +240,61 @@ static void get_mode_protect(struct chanset_t *chan, char *s)
   }
 }
 
-/* returns true if this is one of the channel masks */
+/* Returns true if this is one of the channel masks
+ */
 static int ismodeline(masklist *m, char *user)
 {
-  while (m && m->mask[0]) {
+  for (; m && m->mask[0]; m = m->next)  
     if (!rfc_casecmp(m->mask, user))
       return 1;
-    m = m->next;
-  }
   return 0;
 }
 
-/* returns true if user matches one of the masklist -- drummer */
+/* Returns true if user matches one of the masklist -- drummer
+ */
 static int ismasked(masklist *m, char *user)
 {
-  while (m && m->mask[0]) {
+  for (; m && m->mask[0]; m = m->next)
     if (wild_match(m->mask, user))
       return 1;
-    m = m->next;
-  }
   return 0;
 }
 
-/* destroy a chanset in the list */
-/* does NOT free up memory associated with channel data inside the chanset! */
-static int killchanset(struct chanset_t *chan)
+/* Unlink chanset element from chanset list.
+ */
+inline static int chanset_unlink(struct chanset_t *chan)
 {
-  struct chanset_t *c = chanset, *old = NULL;
+  struct chanset_t	*c, *c_old = NULL;
 
-  while (c) {
+  for (c = chanset; c; c_old = c, c = c->next) {
     if (c == chan) {
-      if (old)
-	old->next = c->next;
+      if (c_old)
+	c_old->next = c->next;
       else
 	chanset = c->next;
-      nfree(c);
       return 1;
     }
-    old = c;
-    c = c->next;
   }
   return 0;
 }
 
 /* Completely removes a channel.
+ *
  * This includes the removal of all channel-bans, -exempts and -invites, as
  * well as all user flags related to the channel.
  */
 static void remove_channel(struct chanset_t *chan)
 {
+   int		 i;
+   module_entry	*me;
+
+   /* Remove the channel from the list, so that noone can pull it
+      away from under our feet during the check_tcl_part() call. */
+   (void) chanset_unlink(chan);
+
+   if ((me = module_find("irc", 1, 3)) != NULL)
+     (me->funcs[IRC_DO_CHANNEL_PART])(chan);
+
    clear_channel(chan, 0);
    noshare = 1;
    /* Remove channel-bans */
@@ -273,13 +307,21 @@ static void remove_channel(struct chanset_t *chan)
    while (chan->invites)
      u_delinvite(chan, chan->invites->mask, 1);
    /* Remove channel specific user flags */
-   user_del_chan(chan->name);
+   user_del_chan(chan->dname);
    noshare = 0;
-   killchanset(chan);
+   nfree(chan->channel.key);
+   for (i = 0; i < 6 && chan->cmode[i].op; i++)
+     nfree(chan->cmode[i].op);
+   if (chan->key)
+     nfree(chan->key);
+   if (chan->rmkey)
+     nfree(chan->rmkey);
+   nfree(chan);
 }
 
-/* bind this to chon and *if* the users console channel == ***
- * then set it to a specific channel */
+/* Bind this to chon and *if* the users console channel == ***
+ * then set it to a specific channel
+ */
 static int channels_chon(char *handle, int idx)
 {
   struct flag_record fr = {FR_CHAN | FR_ANYWH | FR_GLOBAL, 0, 0, 0, 0, 0};
@@ -287,7 +329,7 @@ static int channels_chon(char *handle, int idx)
   struct chanset_t *chan = chanset;
 
   if (dcc[idx].type == &DCC_CHAT) {
-    if (!findchan(dcc[idx].u.chat->con_chan) &&
+    if (!findchan_by_dname(dcc[idx].u.chat->con_chan) &&
 	((dcc[idx].u.chat->con_chan[0] != '*') ||
 	 (dcc[idx].u.chat->con_chan[1] != 0))) {
       get_user_flagrec(dcc[idx].user, &fr, NULL);
@@ -301,7 +343,7 @@ static int channels_chon(char *handle, int idx)
 	find = USER_OP;
       fr.match = FR_CHAN;
       while (chan && !found) {
-	get_user_flagrec(dcc[idx].user, &fr, chan->name);
+	get_user_flagrec(dcc[idx].user, &fr, chan->dname);
 	if (fr.chan & find)
 	  found = 1;
 	else
@@ -310,7 +352,7 @@ static int channels_chon(char *handle, int idx)
       if (!chan)
 	chan = chanset;
       if (chan)
-	strcpy(dcc[idx].u.chat->con_chan, chan->name);
+	strcpy(dcc[idx].u.chat->con_chan, chan->dname);
       else
 	strcpy(dcc[idx].u.chat->con_chan, "*");
     }
@@ -329,29 +371,35 @@ static char *convert_element(char *src, char *dst)
 
 #define PLSMNS(x) (x ? '+' : '-')
 
+/*
+ * Note:
+ *  - We write chanmode "" too, so that the bot won't use default-chanmode
+ *    instead of ""
+ *  - We will write empty need-xxxx too, why not? (less code + lazyness)
+ */
 static void write_channels()
 {
   FILE *f;
   char s[121], w[1024], w2[1024], name[163];
   char need1[242], need2[242], need3[242], need4[242], need5[242];
   struct chanset_t *chan;
+  struct udef_struct *ul;
 
-  Context;
   if (!chanfile[0])
     return;
   sprintf(s, "%s~new", chanfile);
   f = fopen(s, "w");
-  chmod(s, 0600);
+  chmod(s, userfile_perm);
   if (f == NULL) {
     putlog(LOG_MISC, "*", "ERROR writing channel file.");
     return;
   }
   if (!quiet_save)
-    putlog(LOG_MISC, "*", "Writing channel file ...");
+    putlog(LOG_MISC, "*", "Writing channel file...");
   fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
-	  origbotname, ver, ctime(&now));
+	  botnetnick, ver, ctime(&now));
   for (chan = chanset; chan; chan = chan->next) {
-    convert_element(chan->name, name);
+    convert_element(chan->dname, name);
     get_mode_protect(chan, w);
     convert_element(w, w2);
     convert_element(chan->need_op, need1);
@@ -359,43 +407,43 @@ static void write_channels()
     convert_element(chan->need_key, need3);
     convert_element(chan->need_unban, need4);
     convert_element(chan->need_limit, need5);
-    fprintf(f, "channel %s %s%schanmode %s idle-kick %d \
+    fprintf(f, "channel %s %s%schanmode %s idle-kick %d stopnethack-mode %d \
+revenge-mode %d \
 need-op %s need-invite %s need-key %s need-unban %s need-limit %s \
 flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
-flood-kick %d:%d flood-deop %d:%d \
-%cclearbans %cenforcebans %cdynamicbans %cuserbans %cautoop %cbitch \
-%cgreet %cprotectops %cprotectfriends %cdontkickops %cwasoptest \
-%cstatuslog %cstopnethack %crevenge %crevengebot %cautovoice %csecret \
+flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d aop-delay %d:%d \
+%cenforcebans %cdynamicbans %cuserbans %cautoop %cautohalfop %cbitch \
+%cgreet %cprotectops %cprotecthalfops %cprotectfriends %cdontkickops \
+%cstatuslog %crevenge %crevengebot %cautovoice %csecret \
 %cshared %ccycle %cseen %cinactive %cdynamicexempts %cuserexempts \
-%cdynamicinvites %cuserinvites%s\n",
+%cdynamicinvites %cuserinvites %cnodesynch ",
 	channel_static(chan) ? "set" : "add",
 	name,
 	channel_static(chan) ? " " : " { ",
 	w2,
-/* now bot write chanmode "" too,
- * so bot wont use default-chanmode instead of "" -- bugfix
- */
 	chan->idle_kick, /* idle-kick 0 is same as dont-idle-kick (less code)*/
+	chan->stopnethack_mode,
+        chan->revenge_mode,
 	need1, need2, need3, need4, need5,
-/* yes we will write empty need-xxxx too, why not? (less code + lazyness) */
 	chan->flood_pub_thr, chan->flood_pub_time,
         chan->flood_ctcp_thr, chan->flood_ctcp_time,
         chan->flood_join_thr, chan->flood_join_time,
         chan->flood_kick_thr, chan->flood_kick_time,
         chan->flood_deop_thr, chan->flood_deop_time,
-	PLSMNS(channel_clearbans(chan)),
+	chan->flood_nick_thr, chan->flood_nick_time,
+	chan->aop_min, chan->aop_max,
 	PLSMNS(channel_enforcebans(chan)),
 	PLSMNS(channel_dynamicbans(chan)),
 	PLSMNS(!channel_nouserbans(chan)),
 	PLSMNS(channel_autoop(chan)),
+	PLSMNS(channel_autohalfop(chan)),
 	PLSMNS(channel_bitch(chan)),
 	PLSMNS(channel_greet(chan)),
 	PLSMNS(channel_protectops(chan)),
-        PLSMNS(channel_protectfriends(chan)),
+	PLSMNS(channel_protecthalfops(chan)),
+	PLSMNS(channel_protectfriends(chan)),
 	PLSMNS(channel_dontkickops(chan)),
-	PLSMNS(channel_wasoptest(chan)),
 	PLSMNS(channel_logstatus(chan)),
-	PLSMNS(channel_stopnethack(chan)),
 	PLSMNS(channel_revenge(chan)),
 	PLSMNS(channel_revengebot(chan)),
 	PLSMNS(channel_autovoice(chan)),
@@ -404,11 +452,24 @@ flood-kick %d:%d flood-deop %d:%d \
 	PLSMNS(channel_cycle(chan)),
 	PLSMNS(channel_seen(chan)),
 	PLSMNS(channel_inactive(chan)),
-        PLSMNS(channel_dynamicexempts(chan)),
-        PLSMNS(!channel_nouserexempts(chan)),
+	PLSMNS(channel_dynamicexempts(chan)),
+	PLSMNS(!channel_nouserexempts(chan)),
  	PLSMNS(channel_dynamicinvites(chan)),
-        PLSMNS(!channel_nouserinvites(chan)),
-	channel_static(chan) ? "" : " }");
+	PLSMNS(!channel_nouserinvites(chan)),
+	PLSMNS(channel_nodesynch(chan)));
+    for (ul = udef; ul; ul = ul->next) {
+      if (ul->defined && ul->name) {
+	if (ul->type == UDEF_FLAG)
+	  fprintf(f, "%c%s%s ", getudef(ul->values, chan->dname) ? '+' : '-',
+		  "udef-flag-", ul->name);
+	else if (ul->type == UDEF_INT)
+	  fprintf(f, "%s%s %d ", "udef-int-", ul->name, getudef(ul->values,
+		  chan->dname));
+	else
+	  debug1("UDEF-ERROR: unknown type %d", ul->type);
+      }
+    }
+    fprintf(f, "%s\n", channel_static(chan) ? "" : "}");
     if (fflush(f)) {
       putlog(LOG_MISC, "*", "ERROR writing channel file.");
       fclose(f);
@@ -422,7 +483,7 @@ flood-kick %d:%d flood-deop %d:%d \
 
 static void read_channels(int create)
 {
-  struct chanset_t *chan, *chan2;
+  struct chanset_t *chan, *chan_next;
 
   if (!chanfile[0])
     return;
@@ -433,40 +494,46 @@ static void read_channels(int create)
   if (!readtclprog(chanfile) && create) {
     FILE *f;
 
-    /* assume file isnt there & therfore make it */
+    /* Assume file isnt there & therfore make it */
     putlog(LOG_MISC, "*", "Creating channel file");
     f = fopen(chanfile, "w");
     if (!f)
       putlog(LOG_MISC, "*", "Couldn't create channel file: %s.  Dropping",
 	     chanfile);
-    else fclose(f);
+    else
+      fclose(f);
   }
   chan_hack = 0;
-  chan = chanset;
-  while (chan != NULL) {
+  for (chan = chanset; chan; chan = chan_next) {
+    chan_next = chan->next;
     if (chan->status & CHAN_FLAGGED) {
-      putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->name);
-      if (!channel_inactive(chan))
-	dprintf(DP_SERVER, "PART %s\n", chan->name);
-      chan2 = chan->next;
+      putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->dname);
       remove_channel(chan);
-      chan = chan2;
-    } else
-      chan = chan->next;
+    }
   }
 }
 
+static void backup_chanfile()
+{
+  char s[125];
+
+  putlog(LOG_MISC, "*", "Backing up channel file...");
+  egg_snprintf(s, sizeof s, "%s~bak", chanfile);
+  copyfile(chanfile, s);
+}
+
 static void channels_prerehash()
 {
   struct chanset_t *chan;
 
+  /* Flag will be cleared as the channels are re-added by the
+   * config file. Any still flagged afterwards will be removed.
+   */
   for (chan = chanset; chan; chan = chan->next) {
     chan->status |= CHAN_FLAGGED;
-    /* flag will be cleared as the channels are re-added by the config file */
-    /* any still flagged afterwards will be removed */
+    /* Flag is only added to channels read from config file */
     if (chan->status & CHAN_STATIC)
       chan->status &= ~CHAN_STATIC;
-    /* flag is added to channels read from config file */
   }
   setstatic = 1;
 }
@@ -477,13 +544,11 @@ static void channels_rehash()
 
   setstatic = 0;
   read_channels(1);
-  /* remove any extra channels */
+  /* Remove any extra channels, by checking the flag. */
   chan = chanset;
-  while (chan) {
+  for (chan = chanset; chan;) {
     if (chan->status & CHAN_FLAGGED) {
-      putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->name);
-      if (!channel_inactive(chan))
-	dprintf(DP_SERVER, "PART %s\n", chan->name);
+      putlog(LOG_MISC, "*", "No longer supporting channel %s", chan->dname);
       remove_channel(chan);
       chan = chanset;
     } else
@@ -491,11 +556,10 @@ static void channels_rehash()
   }
 }
 
-/* update the add/rem_builtins in channels.c if you add to this list!! */
 static cmd_t my_chon[] =
 {
-  {"*", "", (Function) channels_chon, "channels:chon"},
-  {0, 0, 0, 0}
+  {"*",		"",	(Function) channels_chon,	"channels:chon"},
+  {NULL,	NULL,	NULL,				NULL}
 };
 
 static void channels_report(int idx, int details)
@@ -503,13 +567,11 @@ static void channels_report(int idx, int details)
   struct chanset_t *chan;
   int i;
   char s[1024], s2[100];
-  struct flag_record fr =
-  {FR_CHAN | FR_GLOBAL, 0, 0, 0, 0, 0};
+  struct flag_record fr = {FR_CHAN | FR_GLOBAL, 0, 0, 0, 0, 0};
 
-  chan = chanset;
-  while (chan != NULL) {
+  for (chan = chanset; chan; chan = chan->next) {
     if (idx != DP_STDOUT)
-      get_user_flagrec(dcc[idx].user, &fr, chan->name);
+      get_user_flagrec(dcc[idx].user, &fr, chan->dname);
     if ((idx == DP_STDOUT) || glob_master(fr) || chan_master(fr)) {
       s[0] = 0;
       if (channel_greet(chan))
@@ -525,46 +587,53 @@ static void channels_report(int idx, int details)
       get_mode_protect(chan, s2);
       if (!channel_inactive(chan)) {
 	if (channel_active(chan)) {
-	  dprintf(idx, "    %-10s: %2d member%s enforcing \"%s\" (%s)\n", chan->name,
-		  chan->channel.members, chan->channel.members == 1 ? "," : "s,", s2, s);
+	  /* If it's a !chan, we want to display it's unique name too <cybah> */
+	  if (chan->dname[0]=='!') {
+	    dprintf(idx, "    %-10s: %2d member%s enforcing \"%s\" (%s), "
+	            "unique name %s\n", chan->dname, chan->channel.members,
+	            (chan->channel.members==1) ? "," : "s,", s2, s, chan->name);
+	  } else {
+	    dprintf(idx, "    %-10s: %2d member%s enforcing \"%s\" (%s)\n",
+	            chan->dname, chan->channel.members,
+	            chan->channel.members == 1 ? "," : "s,", s2, s);
+	  }
 	} else {
-	  dprintf(idx, "    %-10s: (%s), enforcing \"%s\"  (%s)\n", chan->name,
-		  channel_pending(chan) ? "pending" : "inactive", s2, s);
+	  dprintf(idx, "    %-10s: (%s), enforcing \"%s\"  (%s)\n", chan->dname,
+		  channel_pending(chan) ? "pending" : "not on channel", s2, s);
 	}
       } else {
-	dprintf(idx, "    %-10s: no IRC support for this channel\n", chan->name);
+	dprintf(idx, "    %-10s: channel is set +inactive\n",
+		chan->dname);
       }
       if (details) {
 	s[0] = 0;
 	i = 0;
-	if (channel_clearbans(chan))
-	  i += my_strcpy(s + i, "clear-bans ");
 	if (channel_enforcebans(chan))
-	  i += my_strcpy(s + i, "enforce-bans ");
+	  i += my_strcpy(s + i, "enforcebans ");
 	if (channel_dynamicbans(chan))
-	  i += my_strcpy(s + i, "dynamic-bans ");
-	if (channel_nouserbans(chan))
-	  i += my_strcpy(s + i, "forbid-user-bans ");
+	  i += my_strcpy(s + i, "dynamicbans ");
+	if (!channel_nouserbans(chan))
+	  i += my_strcpy(s + i, "userbans ");
 	if (channel_autoop(chan))
-	  i += my_strcpy(s + i, "op-on-join ");
+	  i += my_strcpy(s + i, "autoop ");
 	if (channel_bitch(chan))
 	  i += my_strcpy(s + i, "bitch ");
 	if (channel_greet(chan))
 	  i += my_strcpy(s + i, "greet ");
 	if (channel_protectops(chan))
-	  i += my_strcpy(s + i, "protect-ops ");
-        if (channel_protectfriends(chan))
-          i += my_strcpy(s + i, "protect-friends ");
+	  i += my_strcpy(s + i, "protectops ");
+	if (channel_protecthalfops(chan))
+	  i += my_strcpy(s + i, "protecthalfops ");
+	if (channel_protectfriends(chan))
+	  i += my_strcpy(s + i, "protectfriends ");
 	if (channel_dontkickops(chan))
-	  i += my_strcpy(s + i, "dont-kick-ops ");
-	if (channel_wasoptest(chan))
-	  i += my_strcpy(s + i, "was-op-test ");
+	  i += my_strcpy(s + i, "dontkickops ");
 	if (channel_logstatus(chan))
-	  i += my_strcpy(s + i, "log-status ");
+	  i += my_strcpy(s + i, "statuslog ");
 	if (channel_revenge(chan))
 	  i += my_strcpy(s + i, "revenge ");
-	if (channel_stopnethack(chan))
-	  i += my_strcpy(s + i, "stopnethack ");
+	if (channel_revenge(chan))
+	  i += my_strcpy(s + i, "revengebot ");
 	if (channel_secret(chan))
 	  i += my_strcpy(s + i, "secret ");
 	if (channel_shared(chan))
@@ -573,36 +642,48 @@ static void channels_report(int idx, int details)
 	  i += my_strcpy(s + i, "dynamic ");
 	if (channel_autovoice(chan))
 	  i += my_strcpy(s + i, "autovoice ");
+	if (channel_autohalfop(chan))
+	  i += my_strcpy(s + i, "autohalfop ");
 	if (channel_cycle(chan))
 	  i += my_strcpy(s + i, "cycle ");
 	if (channel_seen(chan))
 	  i += my_strcpy(s + i, "seen ");
 	if (channel_dynamicexempts(chan))
-	  i += my_strcpy(s + i, "dynamic-exempts ");
-	if (channel_nouserexempts(chan))
-	  i += my_strcpy(s + i, "forbid-user-exempts ");
+	  i += my_strcpy(s + i, "dynamicexempts ");
+	if (!channel_nouserexempts(chan))
+	  i += my_strcpy(s + i, "userexempts ");
 	if (channel_dynamicinvites(chan))
-	  i += my_strcpy(s + i, "dynamic-invites ");
-	if (channel_nouserinvites(chan))
-	  i += my_strcpy(s + i, "forbid-user-invites ");
+	  i += my_strcpy(s + i, "dynamicinvites ");
+	if (!channel_nouserinvites(chan))
+	  i += my_strcpy(s + i, "userinvites ");
 	if (channel_inactive(chan))
 	  i += my_strcpy(s + i, "inactive ");
+	if (channel_nodesynch(chan))
+	  i += my_strcpy(s + i, "nodesynch ");
 	dprintf(idx, "      Options: %s\n", s);
 	if (chan->need_op[0])
 	  dprintf(idx, "      To get ops I do: %s\n", chan->need_op);
 	if (chan->need_invite[0])
 	  dprintf(idx, "      To get invited I do: %s\n", chan->need_invite);
 	if (chan->need_limit[0])
-	  dprintf(idx, "      To get the channel limit up'd I do: %s\n", chan->need_limit);
+	  dprintf(idx, "      To get the channel limit up'd I do: %s\n",
+		  chan->need_limit);
 	if (chan->need_unban[0])
 	  dprintf(idx, "      To get unbanned I do: %s\n", chan->need_unban);
 	if (chan->need_key[0])
-	  dprintf(idx, "      To get the channel key I do: %s\n", chan->need_key);
+	  dprintf(idx, "      To get the channel key I do: %s\n",
+		  chan->need_key);
 	if (chan->idle_kick)
-	  dprintf(idx, "      Kicking idle users after %d min\n", chan->idle_kick);
+	  dprintf(idx, "      Kicking idle users after %d min\n",
+		  chan->idle_kick);
+	if (chan->stopnethack_mode)
+	  dprintf(idx, "      stopnethack-mode %d\n",
+		  chan->stopnethack_mode);
+        if (chan->revenge_mode)
+          dprintf(idx, "      revenge-mode %d\n",
+                  chan->revenge_mode);
       }
     }
-    chan = chan->next;
   }
   if (details) {
     dprintf(idx, "    Bans last %d mins.\n", ban_time);
@@ -615,24 +696,22 @@ static int expmem_masklist(masklist *m)
 {
   int result = 0;
 
-  while (m) {
+  for (; m; m = m->next) {
     result += sizeof(masklist);
     if (m->mask)
         result += strlen(m->mask) + 1;
     if (m->who)
         result += strlen(m->who) + 1;
-    m = m->next;
   }
   return result;
 }
 
 static int channels_expmem()
 {
-  int tot = 0;
-  struct chanset_t *chan = chanset;
+  int tot = 0, i;
+  struct chanset_t *chan;
 
-  Context;
-  while (chan != NULL) {
+  for (chan = chanset; chan; chan = chan->next) {
     tot += sizeof(struct chanset_t);
 
     tot += strlen(chan->channel.key) + 1;
@@ -644,37 +723,49 @@ static int channels_expmem()
     tot += expmem_masklist(chan->channel.exempt);
     tot += expmem_masklist(chan->channel.invite);
 
-    chan = chan->next;
+    for (i = 0; i < 6 && chan->cmode[i].op; i++)
+      tot += strlen(chan->cmode[i].op) + 1;
+    if (chan->key)
+      tot += strlen(chan->key) + 1;
+    if (chan->rmkey)
+      tot += strlen(chan->rmkey) + 1;
   }
+  tot += expmem_udef(udef);
   return tot;
 }
 
+#if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
 static char *traced_globchanset(ClientData cdata, Tcl_Interp * irp,
-				char *name1, char *name2, int flags)
+				char *name1, CONST char *name2, int flags)
+#else
+static char *traced_globchanset(ClientData cdata, Tcl_Interp * irp, 
+                                char *name1, char *name2, int flags)
+#endif
 {
   char *s;
   char *t;
   int i;
   int items;
+#if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))
+  CONST char **item;
+#else
   char **item;
+#endif
 
-  Context;
   if (flags & (TCL_TRACE_READS | TCL_TRACE_UNSETS)) {
     Tcl_SetVar2(interp, name1, name2, glob_chanset, TCL_GLOBAL_ONLY);
     if (flags & TCL_TRACE_UNSETS)
       Tcl_TraceVar(interp, "global-chanset",
 	    TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
 	    traced_globchanset, NULL);
-  } else { /* write */
+  } else { /* Write */
     s = Tcl_GetVar2(interp, name1, name2, TCL_GLOBAL_ONLY);
     Tcl_SplitList(interp, s, &items, &item);
-    Context;
     for (i = 0; i<items; i++) {
       if (!(item[i]) || (strlen(item[i]) < 2)) continue;
       s = glob_chanset;
       while (s[0]) {
-	t = strchr(s, ' '); /* cant be NULL coz of the extra space */
-	Context;
+	t = strchr(s, ' '); /* Can't be NULL coz of the extra space */
 	t[0] = 0;
 	if (!strcmp(s + 1, item[i] + 1)) {
 	  s[0] = item[i][0]; /* +- */
@@ -694,37 +785,41 @@ static char *traced_globchanset(ClientData cdata, Tcl_Interp * irp,
 
 static tcl_ints my_tcl_ints[] =
 {
-  {"share-greet", 0, 0},
-  {"use-info", &use_info, 0},
-  {"ban-time", &ban_time, 0},
-  {"exempt-time", &exempt_time, 0},
-  {"invite-time", &invite_time, 0},
-  {"must-be-owner", &must_be_owner, 0},
-  {"quiet-save", &quiet_save, 0},
-  {0, 0, 0}
+  {"share-greet",		NULL,				0},
+  {"use-info",			&use_info,			0},
+  {"ban-time",			&ban_time,			0},
+  {"exempt-time",		&exempt_time,			0},
+  {"invite-time",		&invite_time,			0},
+  {"quiet-save",		&quiet_save,			0},
+  {"global-stopnethack-mode",	&global_stopnethack_mode,	0},
+  {"global-revenge-mode",       &global_revenge_mode,           0},
+  {"global-idle-kick",		&global_idle_kick,		0},
+  {NULL,			NULL,				0}
 };
 
 static tcl_coups mychan_tcl_coups[] =
 {
-  {"global-flood-chan", &gfld_chan_thr, &gfld_chan_time},
-  {"global-flood-deop", &gfld_deop_thr, &gfld_deop_time},
-  {"global-flood-kick", &gfld_kick_thr, &gfld_kick_time},
-  {"global-flood-join", &gfld_join_thr, &gfld_join_time},
-  {"global-flood-ctcp", &gfld_ctcp_thr, &gfld_ctcp_time},
-  {0, 0, 0}
+  {"global-flood-chan",		&gfld_chan_thr,		&gfld_chan_time},
+  {"global-flood-deop",		&gfld_deop_thr,		&gfld_deop_time},
+  {"global-flood-kick",		&gfld_kick_thr,		&gfld_kick_time},
+  {"global-flood-join",		&gfld_join_thr,		&gfld_join_time},
+  {"global-flood-ctcp",		&gfld_ctcp_thr,		&gfld_ctcp_time},
+  {"global-flood-nick",		&gfld_nick_thr, 	&gfld_nick_time},
+  {"global-aop-delay",		&global_aop_min,	&global_aop_max},
+  {NULL,			NULL,			NULL}
 };
 
 static tcl_strings my_tcl_strings[] =
 {
-  {"chanfile", chanfile, 120, STR_PROTECT},
-  {"global-chanmode", glob_chanmode, 64, 0},
-  {0, 0, 0, 0}
+  {"chanfile",		chanfile,	120,	STR_PROTECT},
+  {"global-chanmode",	glob_chanmode,	64,	0},
+  {NULL,		NULL,		0,	0}
 };
 
 static char *channels_close()
 {
-  Context;
   write_channels();
+  free_udef(udef);
   rem_builtins(H_chon, my_chon);
   rem_builtins(H_dcc, C_dcc_irc);
   rem_tcl_commands(channels_cmds);
@@ -732,6 +827,7 @@ static char *channels_close()
   rem_tcl_ints(my_tcl_ints);
   rem_tcl_coups(mychan_tcl_coups);
   del_hook(HOOK_USERFILE, (Function) channels_writeuserfile);
+  del_hook(HOOK_BACKUP, (Function) backup_chanfile);
   del_hook(HOOK_REHASH, (Function) channels_rehash);
   del_hook(HOOK_PRE_REHASH, (Function) channels_prerehash);
   del_hook(HOOK_MINUTELY, (Function) check_expired_bans);
@@ -746,7 +842,7 @@ static char *channels_close()
   return NULL;
 }
 
-char *channels_start();
+EXPORT_SCOPE char *channels_start();
 
 static Function channels_table[] =
 {
@@ -779,25 +875,21 @@ static Function channels_table[] =
   (Function) u_sticky_mask,
   (Function) ismasked,
   (Function) add_chanrec_by_handle,
-/* *HOLE* channels_funcs[23] used to be isexempted() <cybah> */
-  (Function) NULL,
+  (Function) NULL, /* [23] used to be isexempted() <cybah> */
   /* 24 - 27 */
   (Function) & exempt_time,
-/* *HOLE* channels_funcs[25] used to be isinvited() <cybah> */
-  (Function) NULL,
+  (Function) NULL, /* [25] used to be isinvited() <cybah> */
   (Function) & invite_time,
   (Function) NULL,
   /* 28 - 31 */
-/* *HOLE* channels_funcs[28] used to be u_setsticky_exempt() <cybah> */
-  (Function) NULL,
+  (Function) NULL, /* [28] used to be u_setsticky_exempt() <cybah> */
   (Function) u_delexempt,
   (Function) u_addexempt,
   (Function) NULL,
   /* 32 - 35 */
-/* *HOLE* channels_funcs[32] used to be u_sticky_exempt() <cybah> */
-  (Function) NULL,
+  (Function) NULL,/* [32] used to be u_sticky_exempt() <cybah> */
   (Function) NULL,
-  (Function) killchanset,
+  (Function) NULL,	/* [34] used to be killchanset().	*/
   (Function) u_delinvite,
   /* 36 - 39 */
   (Function) u_addinvite,
@@ -807,6 +899,11 @@ static Function channels_table[] =
   /* 40 - 43 */
   (Function) write_invites,
   (Function) ismodeline,
+  (Function) initudef,
+  (Function) ngetudef,
+  /* 44 - 47 */
+  (Function) expired_mask,
+  (Function) remove_channel,
 };
 
 char *channels_start(Function * global_funcs)
@@ -823,14 +920,57 @@ char *channels_start(Function * global_funcs)
   gfld_join_time = 60;
   gfld_ctcp_thr = 5;
   gfld_ctcp_time = 60;
-  Context;
+  global_idle_kick = 0;
+  global_aop_min = 5;
+  global_aop_max = 30;
+  setstatic = 0;
+  use_info = 1;
+  ban_time = 60;
+  exempt_time = 0;
+  invite_time = 0;
+  strcpy(chanfile, "chanfile");
+  chan_hack = 0;
+  quiet_save = 0;
+  strcpy(glob_chanmode, "nt");
+  udef = NULL;
+  global_stopnethack_mode = 0;
+  global_revenge_mode = 1;
+  strcpy(glob_chanset,
+         "-enforcebans "
+	 "+dynamicbans "
+	 "+userbans "
+	 "-autoop "
+	 "-bitch "
+	 "+greet "
+	 "+protectops "
+	 "+statuslog "
+	 "-revenge "
+	 "-secret "
+	 "-autovoice "
+	 "+cycle "
+	 "+dontkickops "
+	 "-inactive "
+	 "-protectfriends "
+	 "+shared "
+	 "-seen "
+	 "+userexempts "
+	 "+dynamicexempts "
+	 "+userinvites "
+	 "+dynamicinvites "
+	 "-revengebot "
+	 "-protecthalfops "
+	 "-autohalfop "
+	 "-nodesynch ");
   module_register(MODULE_NAME, channels_table, 1, 0);
-  if (!module_depend(MODULE_NAME, "eggdrop", 104, 0))
-    return "This module needs eggdrop1.4.0 or later";
+  if (!module_depend(MODULE_NAME, "eggdrop", 106, 7)) {
+    module_undepend(MODULE_NAME);
+    return "This module requires Eggdrop 1.6.7 or later.";
+  }
   add_hook(HOOK_MINUTELY, (Function) check_expired_bans);
   add_hook(HOOK_MINUTELY, (Function) check_expired_exempts);
   add_hook(HOOK_MINUTELY, (Function) check_expired_invites);
   add_hook(HOOK_USERFILE, (Function) channels_writeuserfile);
+  add_hook(HOOK_BACKUP, (Function) backup_chanfile);
   add_hook(HOOK_REHASH, (Function) channels_rehash);
   add_hook(HOOK_PRE_REHASH, (Function) channels_prerehash);
   Tcl_TraceVar(interp, "global-chanset",

+ 70 - 21
src/mod/channels.mod/channels.h

@@ -1,22 +1,22 @@
-/* 
+/*
  * channels.h -- part of channels.mod
- * 
- * $Id: channels.h,v 1.10 2000/01/08 21:23:15 per Exp $
+ *
+ * $Id: channels.h,v 1.19 2002/01/02 05:04:53 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -25,7 +25,39 @@
 #ifndef _EGG_MOD_CHANNELS_CHANNELS_H
 #define _EGG_MOD_CHANNELS_CHANNELS_H
 
+/* User defined chanmodes/settings */
+#define UDEF_FLAG 1
+#define UDEF_INT 2
+
+#define MASKREASON_MAX	307	/* Max length of ban/invite/exempt/etc.
+				   reasons.				*/
+#define MASKREASON_LEN	(MASKREASON_MAX + 1)
+
+
 #ifdef MAKING_CHANNELS
+
+/* Structure for udef channel values. Udef setting have one such
+ * structure for each channel where they have a defined value.
+ */
+struct udef_chans {
+  struct udef_chans *next;	/* Ptr to next value.			*/
+  char *chan;			/* Dname of channel name.		*/
+  int value;			/* Actual value.			*/
+};
+
+/* Structure for user defined channel settings.
+ */
+struct udef_struct {
+  struct udef_struct *next;	/* Ptr to next setting.			*/
+  char *name;			/* Name of setting.			*/
+  int defined;			/* Boolean that specifies whether this
+				   flag was defined by, e.g. a Tcl
+				   script yet.				*/
+  int type;			/* Type of setting: UDEF_FLAG, UDEF_INT	*/
+  struct udef_chans *values;	/* Ptr to linked list of udef channel
+				   structures.				*/
+};
+
 static void del_chanrec(struct userrec *u, char *);
 static struct chanuserrec *get_chanrec(struct userrec *u, char *chname);
 static struct chanuserrec *add_chanrec(struct userrec *u, char *chname);
@@ -35,7 +67,8 @@ static void set_handle_chaninfo(struct userrec *bu, char *handle,
 				char *chname, char *info);
 static void set_handle_laston(char *chan, struct userrec *u, time_t n);
 static int u_sticky_mask(maskrec *u, char *uhost);
-static int u_setsticky_mask(struct chanset_t *chan, maskrec *m, char *uhost, int sticky, char *botcmd);
+static int u_setsticky_mask(struct chanset_t *chan, maskrec *m, char *uhost,
+			    int sticky, char *botcmd);
 
 static int u_equals_mask(maskrec *u, char *uhost);
 static int u_match_mask(struct maskrec *rec, char *mask);
@@ -59,7 +92,6 @@ static int write_invites (FILE * f, int idx);
 static void check_expired_invites(void);
 static void write_channels(void);
 static void read_channels(int);
-static int killchanset(struct chanset_t *);
 static void clear_channel(struct chanset_t *, int);
 static void get_mode_protect(struct chanset_t *chan, char *s);
 static void set_mode_protect(struct chanset_t *chan, char *set);
@@ -69,6 +101,18 @@ static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
 			      int items, char **item);
 static int tcl_channel_add(Tcl_Interp * irp, char *, char *);
 static char *convert_element(char *src, char *dst);
+static int expmem_udef(struct udef_struct *);
+static int expmem_udef_chans (struct udef_chans *);
+static void free_udef(struct udef_struct *);
+static void free_udef_chans(struct udef_chans *);
+static int getudef(struct udef_chans *, char *);
+static void initudef(int type, char *, int);
+static void setudef(struct udef_struct *, char *, int);
+static void remove_channel(struct chanset_t *);
+static int ngetudef(char *, char *);
+static int expired_mask(struct chanset_t *chan, char *who);
+inline static int chanset_unlink(struct chanset_t *chan);
+
 #else
 
 /* 4 - 7 */
@@ -82,18 +126,18 @@ static char *convert_element(char *src, char *dst);
 #define del_chanrec ((void (*)(struct userrec *, char *))channels_funcs[10])
 #define set_handle_chaninfo ((void (*)(struct userrec *, char *, char *, char *))channels_funcs[11])
 /* 12 - 15 */
-#define channel_malloc(x) ((void *(*)(int,char*,int))channels_funcs[12])(x,__FILE__,__LINE__)
-#define u_match_mask ((int(*)(maskrec *, char *))channels_funcs[13])
-#define u_equals_mask ((int(*)(maskrec *, char *))channels_funcs[14])
-#define clear_channel ((void(*)(struct chanset_t *,int))channels_funcs[15])
+#define channel_malloc(x) ((void *(*)(int, char *, int))channels_funcs[12])(x,__FILE__,__LINE__)
+#define u_match_mask ((int (*)(maskrec *, char *))channels_funcs[13])
+#define u_equals_mask ((int (*)(maskrec *, char *))channels_funcs[14])
+#define clear_channel ((void (*)(struct chanset_t *, int))channels_funcs[15])
 /* 16 - 19 */
 #define set_handle_laston ((void (*)(char *,struct userrec *,time_t))channels_funcs[16])
 #define ban_time (*(int *)(channels_funcs[17]))
 #define use_info (*(int *)(channels_funcs[18]))
 #define get_handle_chaninfo ((void (*)(char *, char *, char *))channels_funcs[19])
 /* 20 - 23 */
-#define u_sticky_mask ((int(*)(maskrec *, char *))channels_funcs[20])
-#define ismasked ((int(*)(masklist *, char *))channels_funcs[21])
+#define u_sticky_mask ((int (*)(maskrec *, char *))channels_funcs[20])
+#define ismasked ((int (*)(masklist *, char *))channels_funcs[21])
 #define add_chanrec_by_handle ((void (*)(struct userrec *, char *, char *))channels_funcs[22])
 /* *HOLE* channels_funcs[23] used to be isexempted() <cybah> */
 /* 24 - 27 */
@@ -109,20 +153,25 @@ static char *convert_element(char *src, char *dst);
 /* 32 - 35 */
 /* *HOLE* channels_funcs[32] used to be u_sticky_exempt() <cybah> */
 /* *HOLE* channels_funcs[33] used to be u_match_invite() <cybah> */
-#define killchanset ((int (*)(struct chanset_t *))channels_funcs[354)
+/* *HOLE* channels_funcs[34] used to be killchanset().			*/
 #define u_delinvite ((int (*)(struct chanset_t *, char *, int))channels_funcs[35])
 /* 36 - 39 */
 #define u_addinvite ((int (*)(struct chanset_t *, char *, char *, char *, time_t, int))channels_funcs[36])
-#define tcl_channel_add ((int (*)Tcl_Interp *, char *, char *))channels_funcs[37])
-#define tcl_channel_modify ((int (*)Tcl_Interp *, struct chanset_t *, int, char **))channels_funcs[38])
+#define tcl_channel_add ((int (*)(Tcl_Interp *, char *, char *))channels_funcs[37])
+#define tcl_channel_modify ((int (*)(Tcl_Interp *, struct chanset_t *, int, char **))channels_funcs[38])
 #define write_exempts ((int (*)(FILE *, int))channels_funcs[39])
 /* 40 - 43 */
 #define write_invites ((int (*)(FILE *, int))channels_funcs[40])
 #define ismodeline ((int(*)(masklist *, char *))channels_funcs[41])
+#define initudef ((void(*)(int, char *,int))channels_funcs[42])
+#define ngetudef ((int(*)(char *, char *))channels_funcs[43])
+/* 44 - 47 */
+#define expired_mask ((int (*)(struct chanset_t *, char *))channels_funcs[44])
+#define remove_channel ((void (*)(struct chanset_t *))channels_funcs[45])
 
 #endif				/* MAKING_CHANNELS */
 
-/* Macro's here because their functions were replaced by somthing more
+/* Macro's here because their functions were replaced by something more
  * generic. <cybah>
  */
 #define isbanned(chan, user)    ismasked((chan)->channel.ban, user)

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 264 - 297
src/mod/channels.mod/cmdschan.c


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 369 - 185
src/mod/channels.mod/tclchan.c


+ 149 - 0
src/mod/channels.mod/udefchan.c

@@ -0,0 +1,149 @@
+/*
+ * udefchan.c -- part of channels.mod
+ *   user definable channel flags/settings
+ *
+ * $Id: udefchan.c,v 1.7 2002/01/02 03:46:37 guppy Exp $
+ */
+/*
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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.
+ */
+
+static int expmem_udef(struct udef_struct *ul)
+{
+  int i = 0;
+
+  for (; ul; ul = ul->next) {
+    i += sizeof(struct udef_struct);
+    i += strlen(ul->name) + 1;
+    i += expmem_udef_chans(ul->values);
+  }
+  return i;
+}
+
+static int expmem_udef_chans(struct udef_chans *ul)
+{
+  int i = 0;
+
+  for (; ul; ul = ul->next) {
+    i += sizeof(struct udef_chans);
+    i += strlen(ul->chan) + 1;
+  }
+  return i;
+}
+
+static int getudef(struct udef_chans *ul, char *name)
+{
+  int val = 0;
+
+  for (; ul; ul = ul->next)
+    if (!egg_strcasecmp(ul->chan, name)) {
+      val = ul->value;
+      break;
+    }
+  return val;
+}
+
+static int ngetudef(char *name, char *chan)
+{
+  struct udef_struct *l;
+  struct udef_chans *ll;
+
+  for (l = udef; l; l = l->next)
+    if (!egg_strcasecmp(l->name, name)) {
+      for (ll = l->values; ll; ll = ll->next)
+        if (!egg_strcasecmp(ll->chan, chan))
+          return ll->value;
+      break;
+    }
+  return 0;
+}
+
+static void setudef(struct udef_struct *us, char *name, int value)
+{
+  struct udef_chans *ul, *ul_last = NULL;
+
+  for (ul = us->values; ul; ul_last = ul, ul = ul->next)
+    if (!egg_strcasecmp(ul->chan, name)) {
+      ul->value = value;
+      return;
+    }
+
+  ul = nmalloc(sizeof(struct udef_chans));
+  ul->chan = nmalloc(strlen(name) + 1);
+  strcpy(ul->chan, name);
+  ul->value = value;
+  ul->next = NULL;
+  if (ul_last)
+    ul_last->next = ul;
+  else
+    us->values = ul;
+}
+
+static void initudef(int type, char *name, int defined)
+{
+  struct udef_struct *ul, *ul_last = NULL;
+
+  if (strlen(name) < 1)
+    return;
+  for (ul = udef; ul; ul_last = ul, ul = ul->next)
+    if (ul->name && !egg_strcasecmp(ul->name, name)) {
+      if (defined) {
+        debug1("UDEF: %s defined", ul->name);
+        ul->defined = 1;
+      }
+      return;
+    }
+
+  debug2("Creating %s (type %d)", name, type);
+  ul = nmalloc(sizeof(struct udef_struct));
+  ul->name = nmalloc(strlen(name) + 1);
+  strcpy(ul->name, name);
+  if (defined)
+    ul->defined = 1;
+  else
+    ul->defined = 0;
+  ul->type = type;
+  ul->values = NULL;
+  ul->next = NULL;
+  if (ul_last)
+    ul_last->next = ul;
+  else
+    udef = ul;
+}
+
+static void free_udef(struct udef_struct *ul)
+{
+  struct udef_struct *ull;
+
+  for (; ul; ul = ull) {
+    ull = ul->next;
+    free_udef_chans(ul->values);
+    nfree(ul->name);
+    nfree(ul);
+  }
+}
+
+static void free_udef_chans(struct udef_chans *ul)
+{
+  struct udef_chans *ull;
+
+  for (; ul; ul = ull) {
+    ull = ul->next;
+    nfree(ul->chan);
+    nfree(ul);
+  }
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 323 - 283
src/mod/channels.mod/userchan.c


+ 49 - 0
src/mod/compress.mod/Makefile.in

@@ -0,0 +1,49 @@
+# Makefile.in for src/mod/compress.mod/
+# $Id: Makefile.in,v 1.7 2000/09/12 15:26:52 fabian Exp $
+
+ZLIB = @ZLIB@
+srcdir = .
+
+
+doofus:
+	@echo ""
+	@echo "Let's try this from the right directory..."
+	@echo ""
+	@cd ../../../ && make
+
+static: ../compress.o
+	@echo "$(ZLIB)" >> ../mod.xlibs
+
+modules: ../../../compress.$(MOD_EXT)
+
+../compress.o:
+	$(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c $(srcdir)/compress.c
+	rm -f ../compress.o
+	mv compress.o ../
+
+../../../compress.$(MOD_EXT): ../compress.o
+	$(LD) -o ../../../compress.$(MOD_EXT) ../compress.o $(ZLIB) $(XLIBS)
+	$(STRIP) ../../../compress.$(MOD_EXT)
+
+depend:
+	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/compress.c > .depend
+
+clean:
+	@rm -f .depend *.o *.$(MOD_EXT) *~
+
+distclean: clean
+	@rm -f Makefile config.cache config.log config.status config.h compress_config.h
+
+#safety hash
+../compress.o: .././compress.mod/compress.c ../../../src/mod/module.h \
+ ../../../src/main.h ../../../config.h ../../../src/lang.h \
+ ../../../src/eggdrop.h ../../../src/flags.h ../../../src/proto.h \
+ ../../../lush.h ../../../src/misc_file.h ../../../src/cmdt.h \
+ ../../../src/tclegg.h ../../../src/tclhash.h ../../../src/chan.h \
+ ../../../src/users.h ../../../src/compat/compat.h \
+ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \
+ ../../../src/compat/memset.h ../../../src/compat/memcpy.h \
+ ../../../src/compat/strcasecmp.h ../../../src/compat/strftime.h \
+ ../../../src/mod/modvals.h ../../../src/tandem.h \
+ ../../../src/mod/share.mod/share.h ../compress.mod/compress_config.h \
+ ../compress.mod/compress.h ../compress.mod/tclcompress.c

+ 444 - 0
src/mod/compress.mod/compress.c

@@ -0,0 +1,444 @@
+/*
+ * compress.c -- part of compress.mod
+ *   uses the compression library libz to compress and uncompress the
+ *   userfiles during the sharing process
+ *
+ * Written by Fabian Knittel <fknittel@gmx.de>. Based on zlib examples
+ * by Jean-loup Gailly and Miguel Albrecht.
+ *
+ * $Id: compress.c,v 1.14 2002/06/06 18:52:22 wcc Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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.
+ */
+
+#define MODULE_NAME "compress"
+#define MAKING_COMPRESS
+
+#include <string.h>
+#include <errno.h>
+#include <zlib.h>
+
+#include "src/mod/module.h"
+#include "share.mod/share.h"
+
+#include "compress_config.h"
+#ifdef HAVE_MMAP
+#  include <sys/types.h>
+#  include <sys/mman.h>
+#  include <sys/stat.h>
+#endif /* HAVE_MMAP */
+#include "compress.h"
+
+#define BUFLEN	512
+
+
+static Function *global = NULL,
+		*share_funcs = NULL;
+
+static unsigned int compressed_files;	/* Number of files compressed.      */
+static unsigned int uncompressed_files;	/* Number of files uncompressed.    */
+static unsigned int share_compressed;	/* Compress userfiles when sharing? */
+static unsigned int compress_level;	/* Default compression used.	    */
+
+
+static int uncompress_to_file(char *f_src, char *f_target);
+static int compress_to_file(char *f_src, char *f_target, int mode_num);
+static int compress_file(char *filename, int mode_num);
+static int uncompress_file(char *filename);
+static int is_compressedfile(char *filename);
+
+#include "tclcompress.c"
+
+
+/*
+ *    Misc functions.
+ */
+
+static int is_compressedfile(char *filename)
+{
+  char		  buf1[50], buf2[50];
+  FILE		 *fin;
+  register int    len1, len2, i;
+
+  egg_memset(buf1, 0, 50);
+  egg_memset(buf2, 0, 50);
+  if (!is_file(filename))
+    return COMPF_FAILED;
+
+  /* Read data with zlib routines.
+   */
+  fin = gzopen(filename, "rb");
+  if (!fin)
+    return COMPF_FAILED;
+  len1 = gzread(fin, buf1, sizeof(buf1));
+  if (len1 < 0)
+    return COMPF_FAILED;
+  if (gzclose(fin) != Z_OK)
+    return COMPF_FAILED;
+
+  /* Read raw data.
+   */
+  fin = fopen(filename, "rb");
+  if (!fin)
+    return COMPF_FAILED;
+  len2 = fread(buf2, 1, sizeof(buf2), fin);
+  if (ferror(fin))
+    return COMPF_FAILED;
+  fclose(fin);
+
+  /* Compare what we found.
+   */
+  if (len1 != len2)
+    return COMPF_COMPRESSED;
+  for (i = 0; i < sizeof(buf1); i++)
+    if (buf1[i] != buf2[i])
+      return COMPF_COMPRESSED;
+  return COMPF_UNCOMPRESSED;
+}
+
+
+/*
+ *    General compression / uncompression functions
+ */
+
+/* Uncompresses a file `f_src' and saves it as `f_target'.
+ */
+static int uncompress_to_file(char *f_src, char *f_target)
+{
+  char buf[BUFLEN];
+  int len;
+  FILE *fin, *fout;
+
+  if (!is_file(f_src)) {
+    putlog(LOG_MISC, "*", "Failed to uncompress file `%s': not a file.",
+	   f_src);
+    return COMPF_ERROR;
+  }
+  fin = gzopen(f_src, "rb");
+  if (!fin) {
+    putlog(LOG_MISC, "*", "Failed to uncompress file `%s': gzopen failed.",
+	   f_src);
+    return COMPF_ERROR;
+  }
+
+  fout = fopen(f_target, "wb");
+  if (!fout) {
+    putlog(LOG_MISC, "*", "Failed to uncompress file `%s': open failed: %s.",
+	   f_src, strerror(errno));
+    return COMPF_ERROR;
+  }
+
+  while (1) {
+    len = gzread(fin, buf, sizeof(buf));
+    if (len < 0) {
+      putlog(LOG_MISC, "*", "Failed to uncompress file `%s': gzread failed.",
+	     f_src);
+      return COMPF_ERROR;
+    }
+    if (!len)
+      break;
+    if ((int) fwrite(buf, 1, (unsigned int) len, fout) != len) {
+      putlog(LOG_MISC, "*", "Failed to uncompress file `%s': fwrite failed: %s.",
+	     f_src, strerror(errno));
+      return COMPF_ERROR;
+    }
+  }
+  if (fclose(fout)) {
+    putlog(LOG_MISC, "*", "Failed to uncompress file `%s': fclose failed: %s.",
+	   f_src, strerror(errno));
+    return COMPF_ERROR;
+  }
+  if (gzclose(fin) != Z_OK) {
+    putlog(LOG_MISC, "*", "Failed to uncompress file `%s': gzclose failed.",
+	   f_src);
+    return COMPF_ERROR;
+  }
+  uncompressed_files++;
+  return COMPF_SUCCESS;
+}
+
+/* Enforce limits.
+ */
+inline static void adjust_mode_num(int *mode)
+{
+  if (*mode > 9)
+    *mode = 9;
+  else if (*mode < 0)
+    *mode = 0;
+}
+
+#ifdef HAVE_MMAP
+/* Attempt to compress in one go, by mmap'ing the file to memory.
+ */
+static int compress_to_file_mmap(FILE *fout, FILE *fin)
+{
+    int		  len, ifd = fileno(fin);
+    char	 *buf;
+    struct stat	  st;
+
+    /* Find out size of file */
+    if (fstat(ifd, &st) < 0)
+      return COMPF_ERROR;
+    if (st.st_size <= 0)
+      return COMPF_ERROR;
+
+    /* mmap file contents to memory */
+    buf = mmap(0, st.st_size, PROT_READ, MAP_SHARED, ifd, 0);
+    if (buf < 0)
+      return COMPF_ERROR;
+
+    /* Compress the whole file in one go */
+    len = gzwrite(fout, buf, st.st_size);
+    if (len != (int) st.st_size)
+      return COMPF_ERROR;
+
+    munmap(buf, st.st_size);
+    fclose(fin);
+    if (gzclose(fout) != Z_OK)
+      return COMPF_ERROR;
+    return COMPF_SUCCESS;
+}
+#endif /* HAVE_MMAP */
+
+/* Compresses a file `f_src' and saves it as `f_target'.
+ */
+static int compress_to_file(char *f_src, char *f_target, int mode_num)
+{
+  char  buf[BUFLEN], mode[5];
+  FILE *fin, *fout;
+  int   len;
+
+  adjust_mode_num(&mode_num);
+  egg_snprintf(mode, sizeof mode, "wb%d", mode_num);
+
+  if (!is_file(f_src)) {
+    putlog(LOG_MISC, "*", "Failed to compress file `%s': not a file.",
+	   f_src);
+    return COMPF_ERROR;
+  }
+  fin = fopen(f_src, "rb");
+  if (!fin) {
+    putlog(LOG_MISC, "*", "Failed to compress file `%s': open failed: %s.",
+	   f_src, strerror(errno));
+    return COMPF_ERROR;
+  }
+
+  fout = gzopen(f_target, mode);
+  if (!fout) {
+    putlog(LOG_MISC, "*", "Failed to compress file `%s': gzopen failed.",
+	   f_src);
+    return COMPF_ERROR;
+  }
+
+#ifdef HAVE_MMAP
+  if (compress_to_file_mmap(fout, fin) == COMPF_SUCCESS) {
+    compressed_files++;
+    return COMPF_SUCCESS;
+  } else {
+    /* To be on the safe side, close the file before attempting
+     * to write again.
+     */
+    gzclose(fout);
+    fout = gzopen(f_target, mode);
+  }
+#endif /* HAVE_MMAP */
+
+  while (1) {
+    len = fread(buf, 1, sizeof(buf), fin);
+    if (ferror(fin)) {
+      putlog(LOG_MISC, "*", "Failed to compress file `%s': fread failed: %s",
+	     f_src, strerror(errno));
+      return COMPF_ERROR;
+    }
+    if (!len)
+      break;
+    if (gzwrite(fout, buf, (unsigned int) len) != len) {
+      putlog(LOG_MISC, "*", "Failed to compress file `%s': gzwrite failed.",
+	     f_src);
+      return COMPF_ERROR;
+    }
+  }
+  fclose(fin);
+  if (gzclose(fout) != Z_OK) {
+    putlog(LOG_MISC, "*", "Failed to compress file `%s': gzclose failed.",
+	   f_src);
+    return COMPF_ERROR;
+  }
+  compressed_files++;
+  return COMPF_SUCCESS;
+}
+
+/* Compresses a file `filename' and saves it as `filename'.
+ */
+static int compress_file(char *filename, int mode_num)
+{
+  char *temp_fn, randstr[5];
+  int   ret;
+
+  /* Create temporary filename. */
+  temp_fn = nmalloc(strlen(filename) + 5);
+  make_rand_str(randstr, 4);
+  strcpy(temp_fn, filename);
+  strcat(temp_fn, randstr);
+
+  /* Compress file. */
+  ret = compress_to_file(filename, temp_fn, mode_num);
+
+  /* Overwrite old file with compressed version.  Only do so
+   * if the compression routine succeeded.
+   */
+  if (ret == COMPF_SUCCESS)
+    movefile(temp_fn, filename);
+
+  nfree(temp_fn);
+  return ret;
+}
+
+/* Uncompresses a file `filename' and saves it as `filename'.
+ */
+static int uncompress_file(char *filename)
+{
+  char *temp_fn, randstr[5];
+  int   ret;
+
+  /* Create temporary filename. */
+  temp_fn = nmalloc(strlen(filename) + 5);
+  make_rand_str(randstr, 4);
+  strcpy(temp_fn, filename);
+  strcat(temp_fn, randstr);
+
+  /* Uncompress file. */
+  ret = uncompress_to_file(filename, temp_fn);
+
+  /* Overwrite old file with uncompressed version.  Only do so
+   * if the uncompression routine succeeded.
+   */
+  if (ret == COMPF_SUCCESS)
+    movefile(temp_fn, filename);
+
+  nfree(temp_fn);
+  return ret;
+}
+
+
+/*
+ *    Userfile feature releated functions
+ */
+
+static int uff_comp(int idx, char *filename)
+{
+  debug1("Compressing user file for %s.", dcc[idx].nick);
+  return compress_file(filename, compress_level);
+}
+
+static int uff_uncomp(int idx, char *filename)
+{
+  debug1("Uncompressing user file from %s.", dcc[idx].nick);
+  return uncompress_file(filename);
+}
+
+static int uff_ask_compress(int idx)
+{
+  if (share_compressed)
+    return 1;
+  else
+    return 0;
+}
+
+static uff_table_t compress_uff_table[] = {
+  {"compress",	UFF_COMPRESS,	uff_ask_compress, 100, uff_comp, uff_uncomp},
+  {NULL,	0,		NULL,		    0,	   NULL,       NULL}
+};
+
+/*
+ *    Compress module related code
+ */
+
+static tcl_ints my_tcl_ints[] = {
+  {"share-compressed",  	&share_compressed},
+  {"compress-level",		&compress_level},
+  {NULL,                	NULL}
+};
+
+static int compress_expmem(void)
+{
+  return 0;
+}
+
+static int compress_report(int idx, int details)
+{
+  if (details)
+    dprintf(idx, "    Compressed %u file(s), uncompressed %u file(s).\n",
+	    compressed_files, uncompressed_files);
+  return 0;
+}
+
+static char *compress_close()
+{
+  rem_help_reference("compress.help");
+  rem_tcl_commands(my_tcl_cmds);
+  rem_tcl_ints(my_tcl_ints);
+  uff_deltable(compress_uff_table);
+
+  module_undepend(MODULE_NAME);
+  return NULL;
+}
+
+EXPORT_SCOPE char *compress_start();
+
+static Function compress_table[] =
+{
+  /* 0 - 3 */
+  (Function) compress_start,
+  (Function) compress_close,
+  (Function) compress_expmem,
+  (Function) compress_report,
+  /* 4 - 7 */
+  (Function) compress_to_file,
+  (Function) compress_file,
+  (Function) uncompress_to_file,
+  (Function) uncompress_file,
+  /* 8 - 11 */
+  (Function) is_compressedfile,
+};
+
+char *compress_start(Function *global_funcs)
+{
+  global = global_funcs;
+  compressed_files	= 0;
+  uncompressed_files	= 0;
+  share_compressed	= 0;
+  compress_level	= 9;
+
+  module_register(MODULE_NAME, compress_table, 1, 1);
+  if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) {
+    module_undepend(MODULE_NAME);
+    return "This module requires Eggdrop 1.6.0 or later.";
+  }
+  share_funcs = module_depend(MODULE_NAME, "share", 2, 3);
+  if (!share_funcs) {
+    module_undepend(MODULE_NAME);
+    return "This module requires share module 2.3 or later.";
+  }
+
+  uff_addtable(compress_uff_table);
+  add_tcl_ints(my_tcl_ints);
+  add_tcl_commands(my_tcl_cmds);
+  add_help_reference("compress.help");
+  return NULL;
+}

+ 52 - 0
src/mod/compress.mod/compress.h

@@ -0,0 +1,52 @@
+/*
+ * compress.h -- part of src/mod/compress.mod
+ *   header file for the zlib compression module
+ *
+ * $Id: compress.h,v 1.5 2002/01/02 03:46:38 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_MOD_COMPRESS_COMPRESS_H
+#define _EGG_MOD_COMPRESS_COMPRESS_H
+
+#define UFF_COMPRESS	0x000008	/* Compress the user file	*/
+
+typedef enum {
+  COMPF_ERROR,		/* Compression failed.			*/
+  COMPF_SUCCESS		/* Compression succeeded.		*/
+} compf_result;
+
+typedef enum {
+  COMPF_UNCOMPRESSED,	/* File is uncompressed.		*/
+  COMPF_COMPRESSED,	/* File is compressed.			*/
+  COMPF_FAILED		/* Could not determine file type.	*/
+} compf_type;
+
+
+#ifndef MAKING_COMPRESS
+/* 4 - 7 */
+# define compress_to_file   ((int (*)(char *, char *, int))(compress_funcs[4]))
+# define compress_file	    ((int (*)(char *, int))(compress_funcs[5]))
+# define uncompress_to_file ((int (*)(char *, char *))(uncompress_funcs[6]))
+# define uncompress_file    ((int (*)(char *))(uncompress_funcs[7]))
+/* 8 - 11 */
+# define is_compressedfile  ((int (*)(char *))(uncompress_funcs[8]))
+#endif /* !MAKING_COMPRESS */
+
+#endif /* !_EGG_MOD_COMPRESS_COMPRESS_H */

+ 7 - 0
src/mod/compress.mod/compress_config.h.in

@@ -0,0 +1,7 @@
+/* compress_config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define if you have a working `mmap' system call.  */
+#undef HAVE_MMAP
+
+/* Define if you have the getpagesize function.  */
+#undef HAVE_GETPAGESIZE

+ 1049 - 0
src/mod/compress.mod/configure

@@ -0,0 +1,1049 @@
+#! /bin/sh
+# configure  --  Special configure variant for eggdrop modules based on the
+#                GNU autoconf scripts.
+#
+# Automatically created by src/mod/eggautoconf from `configure.in'
+#
+
+echo "running in eggdrop mode."
+# This tells the code in eggmod.sh to search for the file `compress.c'.
+# That way we can make sure we're started from the correct directory.
+ac_egg_uniquefile=compress.c
+
+# Scan for out source directory
+ac_egg_srcdir=.
+for i in $*; do
+  case "${i}" in
+    --srcdir=*)
+      ac_egg_srcdir=`echo ${i} | sed -e 's/^--srcdir=//'`
+    ;;
+  esac
+done
+if test -r ${ac_egg_srcdir}/../eggmod.sh; then
+	. ${ac_egg_srcdir}/../eggmod.sh
+else
+	echo "$0: error: failed to locate eggmod.sh in ${ac_egg_srcdir}/.." >&2
+	exit 1
+fi
+
+# Standard autoconf commands/tests follow below.
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:559: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+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
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:589: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_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 $# -gt 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
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:640: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:672: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 683 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:714: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:719: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:728: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:747: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&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
+
+
+echo $ac_n "checking for gzopen in -lz""... $ac_c" 1>&6
+echo "configure:780: checking for gzopen in -lz" >&5
+ac_lib_var=`echo z'_'gzopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lz  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 788 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gzopen();
+
+int main() {
+gzopen()
+; return 0; }
+EOF
+if { (eval echo configure:799: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  ZLIB="-lz"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:820: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 835 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:841: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 852 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:858: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 869 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:875: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+ac_safe=`echo "zlib.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for zlib.h""... $ac_c" 1>&6
+echo "configure:901: checking for zlib.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 906 "configure"
+#include "confdefs.h"
+#include <zlib.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:911: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+# Disable the module if either the header file or the library
+# are missing.
+if test "x${ZLIB}" = x; then
+  cat >&2 <<EOF
+configure: warning:
+
+  Your system does not provide a working zlib compression library. The
+  compress module will therefore be disabled.
+
+EOF
+  ${srcdir}/../../../misc/modconfig -q --top_srcdir=${srcdir}/../../.. --bindir=../../.. del compress
+else
+  if test "${ac_cv_header_zlib_h}" != yes; then
+    cat >&2 <<EOF
+configure: warning:
+
+  Your system does not provide the necessary zlib header files. The
+  compress module will therefore be disabled.
+
+EOF
+    ${srcdir}/../../../misc/modconfig -q --top_srcdir=${srcdir}/../../.. --bindir=../../.. del compress
+  fi
+fi
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:960: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 965 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:970: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:999: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1004 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* 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_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1027: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:1052: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_func_mmap_fixed_mapped=no
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1060 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+   Here is a matrix of mmap possibilities:
+	mmap private not fixed
+	mmap private fixed at somewhere currently unmapped
+	mmap private fixed at somewhere already mapped
+	mmap shared not fixed
+	mmap shared fixed at somewhere currently unmapped
+	mmap shared fixed at somewhere already mapped
+   For private mappings, we should verify that changes cannot be read()
+   back from the file, nor mmap's back from the file at a different
+   address.  (There have been systems where private was not correctly
+   implemented like the infamous i386 svr4.0, and systems where the
+   VM page cache was not coherent with the filesystem buffer cache
+   like early versions of FreeBSD and possibly contemporary NetBSD.)
+   For shared mappings, we should conversely verify that changes get
+   propogated back to all the places they're supposed to be.
+
+   Grep wants private fixed already mapped.
+   The main things grep needs to know about mmap are:
+   * does it exist and is it safe to write into the mmap'd area
+   * how to use it (BSD variants)  */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h.  */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h.  */
+# ifndef HAVE_SYS_PARAM_H
+#  define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+#  define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+#  ifdef HAVE_SYS_PARAM_H
+#   include <sys/param.h>
+#   ifdef EXEC_PAGESIZE
+#    define getpagesize() EXEC_PAGESIZE
+#   else /* no EXEC_PAGESIZE */
+#    ifdef NBPG
+#     define getpagesize() NBPG * CLSIZE
+#     ifndef CLSIZE
+#      define CLSIZE 1
+#     endif /* no CLSIZE */
+#    else /* no NBPG */
+#     ifdef NBPC
+#      define getpagesize() NBPC
+#     else /* no NBPC */
+#      ifdef PAGESIZE
+#       define getpagesize() PAGESIZE
+#      endif /* PAGESIZE */
+#     endif /* no NBPC */
+#    endif /* no NBPG */
+#   endif /* no EXEC_PAGESIZE */
+#  else /* no HAVE_SYS_PARAM_H */
+#   define getpagesize() 8192	/* punt totally */
+#  endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+	char *data, *data2, *data3;
+	int i, pagesize;
+	int fd;
+
+	pagesize = getpagesize();
+
+	/*
+	 * First, make a file with some known garbage in it.
+	 */
+	data = malloc(pagesize);
+	if (!data)
+		exit(1);
+	for (i = 0; i < pagesize; ++i)
+		*(data + i) = rand();
+	umask(0);
+	fd = creat("conftestmmap", 0600);
+	if (fd < 0)
+		exit(1);
+	if (write(fd, data, pagesize) != pagesize)
+		exit(1);
+	close(fd);
+
+	/*
+	 * Next, try to mmap the file at a fixed address which
+	 * already has something else allocated at it.  If we can,
+	 * also make sure that we see the same garbage.
+	 */
+	fd = open("conftestmmap", O_RDWR);
+	if (fd < 0)
+		exit(1);
+	data2 = malloc(2 * pagesize);
+	if (!data2)
+		exit(1);
+	data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+	if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+	    MAP_PRIVATE | MAP_FIXED, fd, 0L))
+		exit(1);
+	for (i = 0; i < pagesize; ++i)
+		if (*(data + i) != *(data2 + i))
+			exit(1);
+
+	/*
+	 * Finally, make sure that changes to the mapped area
+	 * do not percolate back to the file as seen by read().
+	 * (This is a bug on some variants of i386 svr4.0.)
+	 */
+	for (i = 0; i < pagesize; ++i)
+		*(data2 + i) = *(data2 + i) + 1;
+	data3 = malloc(pagesize);
+	if (!data3)
+		exit(1);
+	if (read(fd, data3, pagesize) != pagesize)
+		exit(1);
+	for (i = 0; i < pagesize; ++i)
+		if (*(data + i) != *(data3 + i))
+			exit(1);
+	close(fd);
+	unlink("conftestmmap");
+	exit(0);
+}
+
+EOF
+if { (eval echo configure:1200: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_func_mmap_fixed_mapped=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# 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.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# 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.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile compress_config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@ZLIB@%$ZLIB%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
+ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uB='\([ 	]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="compress_config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #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.
+cat >> conftest.vals <<\EOF
+s%^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+

+ 48 - 0
src/mod/compress.mod/configure.in

@@ -0,0 +1,48 @@
+dnl Eggdrop compile-time configuration file for src/mod/compress.mod
+dnl
+dnl $Id: configure.in,v 1.3 2001/06/28 19:04:28 guppy Exp $
+
+dnl This file is based on the autoconf m4 macros. Special eggdrop
+dnl macros are used to optimise the size of the resulting configure
+dnl script `./configure'.  Run `../eggautoconf' to update that
+dnl script. You need to have the GNU autoconf package installed
+dnl though.
+
+
+dnl Instead of AC_INIT, we call EGG_INIT().
+sinclude(../eggmod.m4)
+EGG_INIT(compress.c)
+AC_CONFIG_HEADER(compress_config.h)
+
+AC_PROG_CC
+
+AC_CHECK_LIB(z, gzopen, ZLIB="-lz", )
+AC_CHECK_HEADER(zlib.h)
+
+# Disable the module if either the header file or the library
+# are missing.
+if test "x${ZLIB}" = x; then
+  cat >&2 <<EOF
+configure: warning:
+
+  Your system does not provide a working zlib compression library. The
+  compress module will therefore be disabled.
+
+EOF
+  EGG_REMOVE_MOD(compress)
+else
+  if test "${ac_cv_header_zlib_h}" != yes; then
+    cat >&2 <<EOF
+configure: warning:
+
+  Your system does not provide the necessary zlib header files. The
+  compress module will therefore be disabled.
+
+EOF
+    EGG_REMOVE_MOD(compress)
+  fi
+fi
+AC_FUNC_MMAP
+AC_SUBST(ZLIB)
+
+AC_OUTPUT(Makefile)

+ 117 - 0
src/mod/compress.mod/tclcompress.c

@@ -0,0 +1,117 @@
+/*
+ * tclcompress.c -- part of compress.mod
+ *   contains all tcl functions
+ *
+ * Written by Fabian Knittel <fknittel@gmx.de>
+ *
+ * $Id: tclcompress.c,v 1.5 2002/01/02 03:46:38 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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.
+ */
+
+
+#define NEXT_ARG	{ curr_arg++; argc--; }
+
+static int tcl_compress_file STDVAR
+{
+  int	 mode_num = compress_level, result, curr_arg = 1;
+  char	*fn_src = NULL, *fn_target = NULL;
+
+  BADARGS(2, 5, " ?options...? src-file ?target-file?");
+  while ((argc > 1) && ((argv[curr_arg])[0] == '-')) {
+    if (!strcmp(argv[curr_arg], "-level")) {
+      argc--;
+      if (argc <= 1) {
+	Tcl_AppendResult(irp, "option `-level' needs parameter", NULL);
+	return TCL_ERROR;
+      }
+      curr_arg++;
+      mode_num = atoi(argv[curr_arg]);
+    } else {
+      Tcl_AppendResult(irp, "unknown option `", argv[curr_arg], "'", NULL);
+      return TCL_ERROR;
+    }
+    NEXT_ARG;
+  }
+  if (argc <= 1) {
+    Tcl_AppendResult(irp, "expecting src-filename as parameter", NULL);
+    return TCL_ERROR;
+  }
+  fn_src = argv[curr_arg];
+  NEXT_ARG;
+  if (argc > 1) {
+    fn_target = argv[curr_arg];
+    NEXT_ARG;
+  }
+  if (argc > 1) {
+    Tcl_AppendResult(irp, "trailing, unexpected parameter to command", NULL);
+    return TCL_ERROR;
+  }
+
+  if (fn_target)
+    result = compress_to_file(fn_src, fn_target, mode_num);
+  else
+    result = compress_file(fn_src, mode_num);
+
+  if (result)
+    Tcl_AppendResult(irp, "1", NULL);
+  else
+    Tcl_AppendResult(irp, "0", NULL);
+  return TCL_OK;
+}
+
+static int tcl_uncompress_file STDVAR
+{
+  int	 result;
+
+  BADARGS(2, 3, " src-file ?target-file?");
+  if (argc == 2)
+    result = uncompress_file(argv[1]);
+  else
+    result = uncompress_to_file(argv[1], argv[2]);
+
+  if (result)
+    Tcl_AppendResult(irp, "1", NULL);
+  else
+    Tcl_AppendResult(irp, "0", NULL);
+  return TCL_OK;
+}
+
+static int tcl_iscompressed STDVAR
+{
+  int	 result;
+
+  BADARGS(2, 2, " compressed-file");
+  result = is_compressedfile(argv[1]);
+  if (result == COMPF_UNCOMPRESSED)
+    Tcl_AppendResult(irp, "0", NULL);	/* Uncompressed.	*/
+  else if (result == COMPF_COMPRESSED)
+    Tcl_AppendResult(irp, "1", NULL);	/* Compressed.		*/
+  else
+    Tcl_AppendResult(irp, "2", NULL);	/* Failed to detect.	*/
+  return TCL_OK;
+}
+
+
+static tcl_cmds my_tcl_cmds[] =
+{
+  {"compressfile",	tcl_compress_file},
+  {"uncompressfile",	tcl_uncompress_file},
+  {"iscompressed",	tcl_iscompressed},
+  {NULL,		NULL}
+};

+ 25 - 14
src/mod/console.mod/Makefile

@@ -1,33 +1,44 @@
 # Makefile for src/mod/console.mod/
-# $Id: Makefile,v 1.10 1999/12/15 02:32:59 guppy Exp $
+# $Id: Makefile,v 1.14 2000/09/27 19:47:16 fabian Exp $
+
+srcdir = .
+
 
 doofus:
 	@echo ""
 	@echo "Let's try this from the right directory..."
 	@echo ""
-	@cd ../../../; make
+	@cd ../../../ && make
 
 static: ../console.o
 
-modules: ../../../console.so
+modules: ../../../console.$(MOD_EXT)
 
 ../console.o:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c console.c
-	rm -f ../console.o
+	$(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c $(srcdir)/console.c
+	@rm -f ../console.o
 	mv console.o ../
 
-../../../console.so: ../console.o
-	$(LD) -o ../../../console.so ../console.o
-	$(STRIP) ../../../console.so
+../../../console.$(MOD_EXT): ../console.o
+	$(LD) -o ../../../console.$(MOD_EXT) ../console.o $(XLIBS)
+	$(STRIP) ../../../console.$(MOD_EXT)
 
 depend:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -MM *.c > .depend
+	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/console.c > .depend
 
 clean:
-	@rm -f .depend *.o *.so *~
+	@rm -f .depend *.o *.$(MOD_EXT) *~
+distclean: clean
 
 #safety hash
-../console.o: console.c ../module.h ../../../config.h ../../main.h \
- ../../lang.h ../../eggdrop.h ../../flags.h ../../proto.h \
- ../../../lush.h ../../cmdt.h ../../tclegg.h ../../tclhash.h \
- ../../chan.h ../../users.h ../modvals.h ../../tandem.h
+../console.o: .././console.mod/console.c ../../../src/mod/module.h \
+ ../../../src/main.h ../../../config.h ../../../src/lang.h \
+ ../../../src/eggdrop.h ../../../src/flags.h ../../../src/proto.h \
+ ../../../lush.h ../../../src/misc_file.h ../../../src/cmdt.h \
+ ../../../src/tclegg.h ../../../src/tclhash.h ../../../src/chan.h \
+ ../../../src/users.h ../../../src/compat/compat.h \
+ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \
+ ../../../src/compat/memset.h ../../../src/compat/memcpy.h \
+ ../../../src/compat/strcasecmp.h ../../../src/compat/strftime.h \
+ ../../../src/mod/modvals.h ../../../src/tandem.h \
+ ../console.mod/console.h

+ 61 - 63
src/mod/console.mod/console.c

@@ -1,23 +1,23 @@
-/* 
+/*
  * console.c -- part of console.mod
  *   saved console settings based on console.tcl
  *   by cmwagner/billyjoe/D. Senso
- * 
- * $Id: console.c,v 1.15 2000/01/08 21:23:15 per Exp $
+ *
+ * $Id: console.c,v 1.25 2002/06/06 18:52:23 wcc Exp $
  */
-/* 
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -25,8 +25,9 @@
 
 #define MODULE_NAME "console"
 #define MAKING_CONSOLE
-#include "../module.h"
+#include "src/mod/module.h"
 #include <stdlib.h>
+#include "console.h"
 
 static Function *global = NULL;
 static int console_autosave = 0;
@@ -42,14 +43,14 @@ struct console_info {
   int conchan;
 };
 
+static struct user_entry_type USERENTRY_CONSOLE;
+
+
 static int console_unpack(struct userrec *u, struct user_entry *e)
 {
   struct console_info *ci = user_malloc(sizeof(struct console_info));
   char *par, *arg;
 
-  Context;
-  Assert(e);
-  Assert(e->name);
   par = e->u.list->extra;
   arg = newsplit(&par);
   ci->channel = user_malloc(strlen(arg) + 1);
@@ -75,10 +76,6 @@ static int console_pack(struct userrec *u, struct user_entry *e)
   struct console_info *ci;
   int l;
 
-  Assert(e);
-  Assert(e->u.extra);
-  Assert(!e->name);
-
   ci = (struct console_info *) e->u.extra;
 
   l = simple_sprintf(work, "%s %s %s %d %d %d",
@@ -100,18 +97,17 @@ static int console_kill(struct user_entry *e)
 {
   struct console_info *i = e->u.extra;
 
-  Context;
   nfree(i->channel);
   nfree(i);
   nfree(e);
   return 1;
 }
 
-static int console_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
+static int console_write_userfile(FILE *f, struct userrec *u,
+				  struct user_entry *e)
 {
   struct console_info *i = e->u.extra;
 
-  Context;
   if (fprintf(f, "--CONSOLE %s %s %s %d %d %d\n",
 	      i->channel, masktype(i->conflags),
 	      stripmasktype(i->stripflags), i->echoflags,
@@ -129,20 +125,17 @@ static int console_set(struct userrec *u, struct user_entry *e, void *buf)
 
   if (ci != buf) {
     if (ci) {
-      Assert(ci->channel);
       nfree(ci->channel);
       nfree(ci);
     }
-    Context;
-
     ci = e->u.extra = buf;
   }
 
-  /* donut share console info */
+  /* Note: Do not share console info */
   return 1;
 }
 
-static int console_tcl_get(Tcl_Interp * irp, struct userrec *u,
+static int console_tcl_get(Tcl_Interp *irp, struct userrec *u,
 			   struct user_entry *e, int argc, char **argv)
 {
   char work[1024];
@@ -156,7 +149,7 @@ static int console_tcl_get(Tcl_Interp * irp, struct userrec *u,
   return TCL_OK;
 }
 
-int console_tcl_set(Tcl_Interp * irp, struct userrec *u,
+static int console_tcl_set(Tcl_Interp *irp, struct userrec *u,
 		    struct user_entry *e, int argc, char **argv)
 {
   struct console_info *i = e->u.extra;
@@ -165,7 +158,7 @@ int console_tcl_set(Tcl_Interp * irp, struct userrec *u,
   BADARGS(4, 9, " handle CONSOLE channel flags strip echo page conchan");
   if (!i) {
     i = user_malloc(sizeof(struct console_info));
-    bzero(i, sizeof(struct console_info));
+    egg_bzero(i, sizeof(struct console_info));
   }
   if (i->channel)
     nfree(i->channel);
@@ -189,30 +182,31 @@ int console_tcl_set(Tcl_Interp * irp, struct userrec *u,
       }
     }
   }
+  set_user(&USERENTRY_CONSOLE, u, i);
   return TCL_OK;
 }
 
-int console_expmem(struct user_entry *e)
+static int console_expmem(struct user_entry *e)
 {
   struct console_info *i = e->u.extra;
 
-  Context;
   return sizeof(struct console_info) + strlen(i->channel) + 1;
 }
 
-void console_display(int idx, struct user_entry *e)
+static void console_display(int idx, struct user_entry *e)
 {
   struct console_info *i = e->u.extra;
 
-  Context;
   if (dcc[idx].user && (dcc[idx].user->flags & USER_MASTER)) {
-    dprintf(idx, "  Saved Console Settings:\n");
-    dprintf(idx, "    Channel: %s\n", i->channel);
-    dprintf(idx, "    Console flags: %s, Strip flags: %s, Echo: %s\n",
-	    masktype(i->conflags), stripmasktype(i->stripflags),
-	    i->echoflags ? "yes" : "no");
-    dprintf(idx, "    Page setting: %d, Console channel: %s%d\n",
-	    i->page, (i->conchan < 100000) ? "" : "*", i->conchan % 100000);
+    dprintf(idx, "  %s\n", CONSOLE_SAVED_SETTINGS);
+    dprintf(idx, "    %s %s\n", CONSOLE_CHANNEL, i->channel);
+    dprintf(idx, "    %s %s, %s %s, %s %s\n", CONSOLE_FLAGS,
+    	masktype(i->conflags), CONSOLE_STRIPFLAGS,
+	    stripmasktype(i->stripflags), CONSOLE_ECHO,
+	    i->echoflags ? CONSOLE_YES : CONSOLE_NO);
+    dprintf(idx, "    %s %d, %s %s%d\n", CONSOLE_PAGE_SETTING, i->page,
+            CONSOLE_CHANNEL2, (i->conchan < GLOBAL_CHANS) ? "" : "*",
+            i->conchan % GLOBAL_CHANS);
   }
 }
 
@@ -231,14 +225,14 @@ static int console_dupuser(struct userrec *new, struct userrec *old,
 
 static struct user_entry_type USERENTRY_CONSOLE =
 {
-  0,				/* always 0 ;) */
-  0,
+  NULL,				/* always 0 ;) */
+  NULL,
   console_dupuser,
   console_unpack,
   console_pack,
   console_write_userfile,
   console_kill,
-  0,
+  NULL,
   console_set,
   console_tcl_get,
   console_tcl_set,
@@ -282,6 +276,7 @@ static int console_chon(char *handle, int idx)
       if (p) {
 	if (dcc[idx].u.chat->channel >= 0) {
 	    char x[1024];
+
 	    chanout_but(-1, dcc[idx].u.chat->channel,
 			"*** [%s] %s\n", dcc[idx].nick, p);
 	    simple_sprintf(x, "[%s] %s", dcc[idx].nick, p);
@@ -300,7 +295,7 @@ static int console_store(struct userrec *u, int idx, char *par)
 
   if (!i) {
     i = user_malloc(sizeof(struct console_info));
-    bzero(i, sizeof(struct console_info));
+    egg_bzero(i, sizeof(struct console_info));
   }
   if (i->channel)
     nfree(i->channel);
@@ -315,13 +310,14 @@ static int console_store(struct userrec *u, int idx, char *par)
     i->page = 0;
   i->conchan = dcc[idx].u.chat->channel;
   if (par) {
-    dprintf(idx, "Saved Console your Settings:\n");
-    dprintf(idx, "  Channel: %s\n", i->channel);
-    dprintf(idx, "  Console flags: %s, Strip flags: %s, Echo: %s\n",
-	    masktype(i->conflags), stripmasktype(i->stripflags),
-	    i->echoflags ? "yes" : "no");
-    dprintf(idx, "  Page setting: %d, Console channel: %d\n",
-	    i->page, i->conchan);
+    dprintf(idx, "%s\n", CONSOLE_SAVED_SETTINGS2);
+    dprintf(idx, "  %s %s\n", CONSOLE_CHANNEL, i->channel);
+    dprintf(idx, "  %s %s, %s %s, %s %s\n", CONSOLE_FLAGS,
+	    masktype(i->conflags), CONSOLE_STRIPFLAGS,
+	    stripmasktype(i->stripflags), CONSOLE_ECHO,
+	    i->echoflags ? CONSOLE_YES : CONSOLE_NO);
+    dprintf(idx, "  %s %d, %s %d\n", CONSOLE_PAGE_SETTING, i->page,
+            CONSOLE_CHANNEL2, i->conchan);
   }
   set_user(&USERENTRY_CONSOLE, u, i);
   return 0;
@@ -337,44 +333,44 @@ static int console_dostore(int idx)
 
 static tcl_ints myints[] =
 {
-  {"console-autosave", &console_autosave, 0},
-  {"force-channel", &force_channel, 0},
-  {"info-party", &info_party, 0},
-  {0, 0, 0}
+  {"console-autosave",	&console_autosave,	0},
+  {"force-channel",	&force_channel,		0},
+  {"info-party",	&info_party,		0},
+  {NULL,		NULL,			0}
 };
 
 static cmd_t mychon[] =
 {
-  {"*", "", console_chon, "console:chon"},
-  {0, 0, 0, 0}
+  {"*",		"",	console_chon,		"console:chon"},
+  {NULL,	NULL,	NULL,			NULL}
 };
 
 static cmd_t mydcc[] =
 {
-  {"store", "", console_store, NULL},
-  {0, 0, 0, 0}
+  {"store",	"",	console_store,		NULL},
+  {NULL,	NULL,	NULL,			NULL}
 };
 
 static char *console_close()
 {
-  Context;
   rem_builtins(H_chon, mychon);
   rem_builtins(H_dcc, mydcc);
   rem_tcl_ints(myints);
   rem_help_reference("console.help");
   del_entry_type(&USERENTRY_CONSOLE);
+  del_lang_section("console");
   module_undepend(MODULE_NAME);
   return NULL;
 }
 
-char *console_start();
+EXPORT_SCOPE char *console_start();
 
 static Function console_table[] =
 {
   (Function) console_start,
   (Function) console_close,
-  (Function) 0,
-  (Function) 0,
+  (Function) NULL,
+  (Function) NULL,
   (Function) console_dostore,
 };
 
@@ -382,15 +378,17 @@ char *console_start(Function * global_funcs)
 {
   global = global_funcs;
 
-  Context;
   module_register(MODULE_NAME, console_table, 1, 1);
-  if (!module_depend(MODULE_NAME, "eggdrop", 104, 0))
-    return "This module requires eggdrop1.4.0 or later";
+  if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) {
+    module_undepend(MODULE_NAME);
+    return "This module requires Eggdrop 1.6.0 or later.";
+  }
   add_builtins(H_chon, mychon);
   add_builtins(H_dcc, mydcc);
   add_tcl_ints(myints);
   add_help_reference("console.help");
   USERENTRY_CONSOLE.get = def_get;
   add_entry_type(&USERENTRY_CONSOLE);
+  add_lang_section("console");
   return NULL;
 }

+ 38 - 0
src/mod/console.mod/console.h

@@ -0,0 +1,38 @@
+/*
+ * console.h -- part of console.mod
+ *
+ * $Id: console.h,v 1.3 2002/01/02 03:46:38 guppy Exp $
+ */
+/*
+ * Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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 _EGG_MOD_CONSOLE_CONSOLE_H
+#define _EGG_MOD_CONSOLE_CONSOLE_H
+
+#define CONSOLE_SAVED_SETTINGS	get_language(0xb040)
+#define CONSOLE_SAVED_SETTINGS2	get_language(0xb041)
+#define CONSOLE_CHANNEL		get_language(0xb042)
+#define CONSOLE_FLAGS		get_language(0xb043)
+#define CONSOLE_STRIPFLAGS	get_language(0xb044)
+#define CONSOLE_ECHO		get_language(0xb045)
+#define CONSOLE_PAGE_SETTING	get_language(0xb046)
+#define CONSOLE_CHANNEL2	get_language(0xb047)
+#define CONSOLE_YES		get_language(0xb048)
+#define CONSOLE_NO		get_language(0xb049)
+
+#endif				/* _EGG_MOD_CONSOLE_CONSOLE_H */

+ 25 - 15
src/mod/ctcp.mod/Makefile

@@ -1,34 +1,44 @@
 # Makefile for src/mod/ctcp.mod/
-# $Id: Makefile,v 1.10 1999/12/15 02:32:59 guppy Exp $
+# $Id: Makefile,v 1.11 2000/09/12 15:26:52 fabian Exp $
+
+srcdir = .
+
 
 doofus:
 	@echo ""
 	@echo "Let's try this from the right directory..."
 	@echo ""
-	@cd ../../../; make
+	@cd ../../../ && make
 
 static: ../ctcp.o
 
-modules: ../../../ctcp.so
+modules: ../../../ctcp.$(MOD_EXT)
 
 ../ctcp.o:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c ctcp.c
-	rm -f ../ctcp.o
+	$(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c $(srcdir)/ctcp.c
+	@rm -f ../ctcp.o
 	mv ctcp.o ../
 
-../../../ctcp.so: ../ctcp.o
-	$(LD) -o ../../../ctcp.so ../ctcp.o
-	$(STRIP) ../../../ctcp.so
+../../../ctcp.$(MOD_EXT): ../ctcp.o
+	$(LD) -o ../../../ctcp.$(MOD_EXT) ../ctcp.o
+	$(STRIP) ../../../ctcp.$(MOD_EXT)
 
 depend:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -MM *.c > .depend
+	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/ctcp.c > .depend
 
 clean:
-	@rm -f .depend *.o *.so *~
+	@rm -f .depend *.o *.$(MOD_EXT) *~
+distclean: clean
 
 #safety hash
-../ctcp.o: ctcp.c ctcp.h ../module.h ../../../config.h ../../main.h \
- ../../lang.h ../../eggdrop.h ../../flags.h ../../proto.h \
- ../../../lush.h ../../cmdt.h ../../tclegg.h ../../tclhash.h \
- ../../chan.h ../../users.h ../modvals.h ../../tandem.h \
- ../server.mod/server.h
+../ctcp.o: .././ctcp.mod/ctcp.c ../ctcp.mod/ctcp.h \
+ ../../../src/mod/module.h ../../../src/main.h ../../../config.h \
+ ../../../src/lang.h ../../../src/eggdrop.h ../../../src/flags.h \
+ ../../../src/proto.h ../../../lush.h ../../../src/misc_file.h \
+ ../../../src/cmdt.h ../../../src/tclegg.h ../../../src/tclhash.h \
+ ../../../src/chan.h ../../../src/users.h ../../../src/compat/compat.h \
+ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \
+ ../../../src/compat/memset.h ../../../src/compat/memcpy.h \
+ ../../../src/compat/strcasecmp.h ../../../src/compat/strftime.h \
+ ../../../src/mod/modvals.h ../../../src/tandem.h \
+ ../../../src/mod/server.mod/server.h

+ 91 - 88
src/mod/ctcp.mod/ctcp.c

@@ -1,23 +1,23 @@
-/* 
+/*
  * ctcp.c -- part of ctcp.mod
  *   all the ctcp handling (except DCC, it's special ;)
- * 
- * $Id: ctcp.c,v 1.5 2000/01/08 21:23:15 per Exp $
+ *
+ * $Id: ctcp.c,v 1.18 2002/06/06 18:52:23 wcc Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.
@@ -26,23 +26,23 @@
 #define MODULE_NAME "ctcp"
 #define MAKING_CTCP
 #include "ctcp.h"
-#include "../module.h"
-#include "../server.mod/server.h"
+#include "src/mod/module.h"
+#include "server.mod/server.h"
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
 static Function *global = NULL, *server_funcs = NULL;
 
-static char ctcp_version[256];
-static char ctcp_finger[256];
-static char ctcp_userinfo[256];
+static char ctcp_version[121];
+static char ctcp_finger[121];
+static char ctcp_userinfo[121];
 static int ctcp_mode = 0;
 
+
 static int ctcp_FINGER(char *nick, char *uhost, char *handle,
 		       char *object, char *keyword, char *text)
 {
-  Context;
-  if ((ctcp_finger[0]) && (ctcp_mode != 1))
+  if (ctcp_mode != 1 && ctcp_finger[0])
     simple_sprintf(ctcp_reply, "%s\001FINGER %s\001", ctcp_reply, ctcp_finger);
   return 1;
 }
@@ -50,8 +50,7 @@ static int ctcp_FINGER(char *nick, char *uhost, char *handle,
 static int ctcp_ECHOERR(char *nick, char *uhost, char *handle,
 			char *object, char *keyword, char *text)
 {
-  Context;
-  if ((strlen(text) <= 80) && (ctcp_mode != 1))
+  if (ctcp_mode != 1 && strlen(text) <= 80)
     simple_sprintf(ctcp_reply, "%s\001%s %s\001", ctcp_reply, keyword, text);
   return 1;
 }
@@ -62,29 +61,26 @@ static int ctcp_PING(char *nick, char *uhost, char *handle,
   struct userrec *u = get_user_by_handle(userlist, handle);
   int atr = u ? u->flags : 0;
 
-  Context;
-  if ((ctcp_mode != 1) || ((atr & (USER_OP)))) {
-    if (strlen(text) <= 80)	/* bitch ignores > 80 */
+  if ((ctcp_mode != 1 || (atr & USER_OP)) && strlen(text) <= 80)
       simple_sprintf(ctcp_reply, "%s\001%s %s\001", ctcp_reply, keyword, text);
-  }
   return 1;
 }
 
 static int ctcp_VERSION(char *nick, char *uhost, char *handle,
 			char *object, char *keyword, char *text)
 {
-  Context;
-  if ((ctcp_version[0]) && (ctcp_mode != 1))
-    simple_sprintf(ctcp_reply, "%s\001VERSION %s\001", ctcp_reply, ctcp_version);
+  if (ctcp_mode != 1 && ctcp_version[0])
+    simple_sprintf(ctcp_reply, "%s\001VERSION %s\001", ctcp_reply,
+		   ctcp_version);
   return 1;
 }
 
 static int ctcp_USERINFO(char *nick, char *uhost, char *handle,
 			 char *object, char *keyword, char *text)
 {
-  Context;
-  if ((ctcp_userinfo[0]) && (ctcp_mode != 1))
-    simple_sprintf(ctcp_reply, "%s\001USERINFO %s\001", ctcp_reply, ctcp_userinfo);
+  if (ctcp_mode != 1 && ctcp_userinfo[0])
+    simple_sprintf(ctcp_reply, "%s\001USERINFO %s\001", ctcp_reply,
+		   ctcp_userinfo);
   return 1;
 }
 
@@ -93,34 +89,33 @@ static int ctcp_CLIENTINFO(char *nick, char *uhosr, char *handle,
 {
   char *p = NULL;
 
-  Context;
-  if ((ctcp_mode == 1))
+  if (ctcp_mode == 1)
     return 1;
-  if (!msg[0])
+  else if (!msg[0])
     p = CLIENTINFO;
-  else if (!strcasecmp(msg, "sed"))
+  else if (!egg_strcasecmp(msg, "sed"))
     p = CLIENTINFO_SED;
-  else if (!strcasecmp(msg, "version"))
+  else if (!egg_strcasecmp(msg, "version"))
     p = CLIENTINFO_VERSION;
-  else if (!strcasecmp(msg, "clientinfo"))
+  else if (!egg_strcasecmp(msg, "clientinfo"))
     p = CLIENTINFO_CLIENTINFO;
-  else if (!strcasecmp(msg, "userinfo"))
+  else if (!egg_strcasecmp(msg, "userinfo"))
     p = CLIENTINFO_USERINFO;
-  else if (!strcasecmp(msg, "errmsg"))
+  else if (!egg_strcasecmp(msg, "errmsg"))
     p = CLIENTINFO_ERRMSG;
-  else if (!strcasecmp(msg, "finger"))
+  else if (!egg_strcasecmp(msg, "finger"))
     p = CLIENTINFO_FINGER;
-  else if (!strcasecmp(msg, "time"))
+  else if (!egg_strcasecmp(msg, "time"))
     p = CLIENTINFO_TIME;
-  else if (!strcasecmp(msg, "action"))
+  else if (!egg_strcasecmp(msg, "action"))
     p = CLIENTINFO_ACTION;
-  else if (!strcasecmp(msg, "dcc"))
+  else if (!egg_strcasecmp(msg, "dcc"))
     p = CLIENTINFO_DCC;
-  else if (!strcasecmp(msg, "utc"))
+  else if (!egg_strcasecmp(msg, "utc"))
     p = CLIENTINFO_UTC;
-  else if (!strcasecmp(msg, "ping"))
+  else if (!egg_strcasecmp(msg, "ping"))
     p = CLIENTINFO_PING;
-  else if (!strcasecmp(msg, "echo"))
+  else if (!egg_strcasecmp(msg, "echo"))
     p = CLIENTINFO_ECHO;
   if (p == NULL) {
     simple_sprintf(ctcp_reply,
@@ -134,13 +129,12 @@ static int ctcp_CLIENTINFO(char *nick, char *uhosr, char *handle,
 static int ctcp_TIME(char *nick, char *uhost, char *handle, char *object,
 		     char *keyword, char *text)
 {
-  char tms[81];
+  char tms[25];
 
-  Context;
-  if ((ctcp_mode == 1))
+  if (ctcp_mode == 1)
     return 1;
-  strcpy(tms, ctime(&now));
-  tms[strlen(tms) - 1] = 0;
+  strncpy(tms, ctime(&now), 24);
+  tms[24] = 0;
   simple_sprintf(ctcp_reply, "%s\001TIME %s\001", ctcp_reply, tms);
   return 1;
 }
@@ -149,59 +143,63 @@ static int ctcp_CHAT(char *nick, char *uhost, char *handle, char *object,
 		     char *keyword, char *text)
 {
   struct userrec *u = get_user_by_handle(userlist, handle);
-  int atr = u ? u->flags : 0, i, ix = (-1);
+  int atr = u ? u->flags : 0, i;
 
-  Context;
   if ((atr & (USER_PARTY | USER_XFER)) ||
       ((atr & USER_OP) && !require_p)) {
+
+    if (u_pass_match(u, "-")) {
+      simple_sprintf(ctcp_reply, "%s\001ERROR no password set\001", ctcp_reply);
+      return 1;
+    }
+
     for (i = 0; i < dcc_total; i++) {
       if ((dcc[i].type->flags & DCT_LISTEN) &&
-	  ((!strcmp(dcc[i].nick, "(telnet)")) ||
-	   (!strcmp(dcc[i].nick, "(users)")))) {
-	ix = i;
-	/* do me a favour and don't change this back to a CTCP reply,
-	 * CTCP replies are NOTICE's this has to be a PRIVMSG
-	 * -poptix 5/1/1997 */
+	  (!strcmp(dcc[i].nick, "(telnet)") ||
+	   !strcmp(dcc[i].nick, "(users)"))) {
+        /* Do me a favour and don't change this back to a CTCP reply,
+         * CTCP replies are NOTICE's this has to be a PRIVMSG
+         * -poptix 5/1/1997 */
 	dprintf(DP_SERVER, "PRIVMSG %s :\001DCC CHAT chat %lu %u\001\n",
 		nick,
 		iptolong(natip[0] ? (IP) inet_addr(natip) : getmyip()),
-		dcc[ix].port);
+		dcc[i].port);
+        return 1;
       }
     }
-    if (ix < 0)
-      simple_sprintf(ctcp_reply,
-		     "%s\001ERROR no telnet port\001", ctcp_reply);
+    simple_sprintf(ctcp_reply, "%s\001ERROR no telnet port\001", ctcp_reply);
   }
   return 1;
 }
 
 static cmd_t myctcp[] =
 {
-  {"FINGER", "", ctcp_FINGER, NULL},
-  {"ECHO", "", ctcp_ECHOERR, NULL},
-  {"PING", "", ctcp_PING, NULL},
-  {"ERRMSG", "", ctcp_ECHOERR, NULL},
-  {"VERSION", "", ctcp_VERSION, NULL},
-  {"USERINFO", "", ctcp_USERINFO, NULL},
-  {"CLIENTINFO", "", ctcp_CLIENTINFO, NULL},
-  {"TIME", "", ctcp_TIME, NULL},
-  {"CHAT", "", ctcp_CHAT, NULL},
-  {0, 0, 0, 0}
+  {"FINGER",		"",	ctcp_FINGER,		NULL},
+  {"ECHO",		"",	ctcp_ECHOERR,		NULL},
+  {"PING",		"",	ctcp_PING,		NULL},
+  {"ERRMSG",		"",	ctcp_ECHOERR,		NULL},
+  {"VERSION",		"",	ctcp_VERSION,		NULL},
+  {"USERINFO",		"",	ctcp_USERINFO,		NULL},
+  {"CLIENTINFO",	"",	ctcp_CLIENTINFO,	NULL},
+  {"TIME",		"",	ctcp_TIME,		NULL},
+  {"CHAT",		"",	ctcp_CHAT,		NULL},
+  {NULL,		NULL,	NULL,			NULL}
 };
 
 static tcl_strings mystrings[] =
 {
-  {"ctcp-version", ctcp_version, 120, 0},
-  {"ctcp-finger", ctcp_finger, 120, 0},
-  {"ctcp-userinfo", ctcp_userinfo, 120, 0},
-  {0, 0, 0, 0}
+  {"ctcp-version",	ctcp_version,	120,	0},
+  {"ctcp-finger",	ctcp_finger,	120,	0},
+  {"ctcp-userinfo",	ctcp_userinfo,	120,	0},
+  {NULL,		NULL,		0,	0}
 };
 
 static tcl_ints myints[] =
 {
-  {"ctcp-mode", &ctcp_mode},
-  {0, 0}
+  {"ctcp-mode",		&ctcp_mode},
+  {NULL,		NULL}
 };
+
 static char *ctcp_close()
 {
   rem_tcl_strings(mystrings);
@@ -212,39 +210,44 @@ static char *ctcp_close()
   return NULL;
 }
 
-char *ctcp_start();
+EXPORT_SCOPE char *ctcp_start();
 
 static Function ctcp_table[] =
 {
   (Function) ctcp_start,
   (Function) ctcp_close,
-  (Function) 0,
-  (Function) 0,
+  (Function) NULL,
+  (Function) NULL,
 };
 
 char *ctcp_start(Function * global_funcs)
 {
   global = global_funcs;
 
-  Context;
   module_register(MODULE_NAME, ctcp_table, 1, 0);
-  if (!(server_funcs = module_depend(MODULE_NAME, "server", 1, 0)))
-    return "You need the server module to use the ctcp module.";
+  if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) {
+    module_undepend(MODULE_NAME);
+    return "This module requires Eggdrop 1.6.0 or later.";
+  }
+  if (!(server_funcs = module_depend(MODULE_NAME, "server", 1, 0))) {
+    module_undepend(MODULE_NAME);
+    return "This module requires server module 1.0 or later.";
+  }
   add_tcl_strings(mystrings);
   add_tcl_ints(myints);
   add_builtins(H_ctcp, myctcp);
   add_help_reference("ctcp.help");
   if (!ctcp_version[0]) {
-    strncpy(ctcp_version, ver, 160);
-    ctcp_version[160] = 0;
+    strncpy(ctcp_version, ver, 120);
+    ctcp_version[120] = 0;
   }
   if (!ctcp_finger[0]) {
-    strncpy(ctcp_finger, ver, 160);
-    ctcp_finger[160] = 0;
+    strncpy(ctcp_finger, ver, 120);
+    ctcp_finger[120] = 0;
   }
   if (!ctcp_userinfo[0]) {
-    strncpy(ctcp_userinfo, ver, 160);
-    ctcp_userinfo[160] = 0;
+    strncpy(ctcp_userinfo, ver, 120);
+    ctcp_userinfo[120] = 0;
   }
   return NULL;
 }

+ 9 - 9
src/mod/ctcp.mod/ctcp.h

@@ -1,23 +1,23 @@
-/* 
+/*
  * ctcp.h -- part of ctcp.mod
  *   all the defines for ctcp.c
- * 
- * $Id: ctcp.h,v 1.4 2000/01/08 21:23:15 per Exp $
+ *
+ * $Id: ctcp.h,v 1.5 2002/01/02 03:46:38 guppy Exp $
  */
-/* 
- * Copyright (C) 1997  Robey Pointer
- * Copyright (C) 1999, 2000  Eggheads
- * 
+/*
+ * Copyright (C) 1997 Robey Pointer
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
  * 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.

+ 49 - 0
src/mod/dns.mod/Makefile.in

@@ -0,0 +1,49 @@
+# Makefile for src/mod/dns.mod/
+# $Id: Makefile.in,v 1.8 2001/07/24 15:08:22 guppy Exp $
+
+RESLIB = @RESLIB@
+RESINCLUDE = @RESINCLUDE@
+srcdir = .
+
+
+doofus:
+	@echo ""
+	@echo "Let's try this from the right directory..."
+	@echo ""
+	@cd ../../../ && make
+
+static: ../dns.o
+	@echo "$(RESLIB)" >> ../mod.xlibs
+
+modules: ../../../dns.$(MOD_EXT)
+
+../dns.o:
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(RESINCLUDE) -DMAKING_MODS -c $(srcdir)/dns.c
+	@rm -f ../dns.o
+	mv dns.o ../
+
+../../../dns.$(MOD_EXT): ../dns.o
+	$(LD) -o ../../../dns.$(MOD_EXT) ../dns.o $(RESLIB)
+	$(STRIP) ../../../dns.$(MOD_EXT)
+
+depend:
+	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/dns.c > .depend
+
+clean:
+	@rm -f .depend *.o *.$(MOD_EXT) *~
+
+distclean: clean
+	@rm -f Makefile config.cache config.log config.status
+
+#safety hash
+../dns.o: .././dns.mod/dns.c ../../../src/mod/module.h \
+ ../../../src/main.h ../../../config.h ../../../src/lang.h \
+ ../../../src/eggdrop.h ../../../src/flags.h ../../../src/proto.h \
+ ../../../lush.h ../../../src/misc_file.h ../../../src/cmdt.h \
+ ../../../src/tclegg.h ../../../src/tclhash.h ../../../src/chan.h \
+ ../../../src/users.h ../../../src/compat/compat.h \
+ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \
+ ../../../src/compat/memset.h ../../../src/compat/memcpy.h \
+ ../../../src/compat/strcasecmp.h ../../../src/compat/strftime.h \
+ ../../../src/mod/modvals.h ../../../src/tandem.h ../dns.mod/dns.h \
+ ../dns.mod/coredns.c

+ 1115 - 0
src/mod/dns.mod/configure

@@ -0,0 +1,1115 @@
+#! /bin/sh
+# configure  --  Special configure variant for eggdrop modules based on the
+#                GNU autoconf scripts.
+#
+# Automatically created by src/mod/eggautoconf from `configure.in'
+#
+
+echo "running in eggdrop mode."
+# This tells the code in eggmod.sh to search for the file `coredns.c'.
+# That way we can make sure we're started from the correct directory.
+ac_egg_uniquefile=coredns.c
+
+# Scan for out source directory
+ac_egg_srcdir=.
+for i in $*; do
+  case "${i}" in
+    --srcdir=*)
+      ac_egg_srcdir=`echo ${i} | sed -e 's/^--srcdir=//'`
+    ;;
+  esac
+done
+if test -r ${ac_egg_srcdir}/../eggmod.sh; then
+	. ${ac_egg_srcdir}/../eggmod.sh
+else
+	echo "$0: error: failed to locate eggmod.sh in ${ac_egg_srcdir}/.." >&2
+	exit 1
+fi
+
+# Standard autoconf commands/tests follow below.
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:559: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+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
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:589: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_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 $# -gt 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
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:640: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:672: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 683 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:714: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:719: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:728: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:747: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&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
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:779: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 784 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:795: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_cygwin=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+
+dns_reslib_avail="true"
+echo $ac_n "checking for res_init""... $ac_c" 1>&6
+echo "configure:814: checking for res_init" >&5
+if eval "test \"`echo '$''{'ac_cv_func_res_init'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 819 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char res_init(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char res_init();
+
+int main() {
+
+/* 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_res_init) || defined (__stub___res_init)
+choke me
+#else
+res_init();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:842: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_res_init=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_res_init=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'res_init`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for res_init in -lresolv""... $ac_c" 1>&6
+echo "configure:860: checking for res_init in -lresolv" >&5
+ac_lib_var=`echo resolv'_'res_init | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lresolv  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 868 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char res_init();
+
+int main() {
+res_init()
+; return 0; }
+EOF
+if { (eval echo configure:879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  RESLIB="-lresolv"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for res_init in -lbind""... $ac_c" 1>&6
+echo "configure:898: checking for res_init in -lbind" >&5
+ac_lib_var=`echo bind'_'res_init | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lbind  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 906 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char res_init();
+
+int main() {
+res_init()
+; return 0; }
+EOF
+if { (eval echo configure:917: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  RESLIB="-lbind"
+else
+  echo "$ac_t""no" 1>&6
+      dns_reslib_avail="false";
+    
+fi
+  
+fi
+
+fi
+
+if test "${dns_reslib_avail}" = false; then
+  dns_reslib_avail="true"
+  echo $ac_n "checking for __res_init""... $ac_c" 1>&6
+echo "configure:946: checking for __res_init" >&5
+if eval "test \"`echo '$''{'ac_cv_func___res_init'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 951 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char __res_init(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char __res_init();
+
+int main() {
+
+/* 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___res_init) || defined (__stub_____res_init)
+choke me
+#else
+__res_init();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:974: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func___res_init=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func___res_init=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'__res_init`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for __res_init in -lresolv""... $ac_c" 1>&6
+echo "configure:992: checking for __res_init in -lresolv" >&5
+ac_lib_var=`echo resolv'_'__res_init | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lresolv  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1000 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char __res_init();
+
+int main() {
+__res_init()
+; return 0; }
+EOF
+if { (eval echo configure:1011: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  RESLIB="-lresolv"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for __res_init in -lbind""... $ac_c" 1>&6
+echo "configure:1030: checking for __res_init in -lbind" >&5
+ac_lib_var=`echo bind'_'__res_init | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lbind  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1038 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char __res_init();
+
+int main() {
+__res_init()
+; return 0; }
+EOF
+if { (eval echo configure:1049: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  RESLIB="-lbind"
+else
+  echo "$ac_t""no" 1>&6
+        dns_reslib_avail="false";
+      
+fi
+    
+fi
+  
+fi
+fi
+
+echo $ac_n "checking for res_mkquery""... $ac_c" 1>&6
+echo "configure:1077: checking for res_mkquery" >&5
+if eval "test \"`echo '$''{'ac_cv_func_res_mkquery'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1082 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char res_mkquery(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char res_mkquery();
+
+int main() {
+
+/* 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_res_mkquery) || defined (__stub___res_mkquery)
+choke me
+#else
+res_mkquery();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_res_mkquery=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_res_mkquery=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'res_mkquery`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for res_mkquery in -lresolv""... $ac_c" 1>&6
+echo "configure:1123: checking for res_mkquery in -lresolv" >&5
+ac_lib_var=`echo resolv'_'res_mkquery | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lresolv  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1131 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char res_mkquery();
+
+int main() {
+res_mkquery()
+; return 0; }
+EOF
+if { (eval echo configure:1142: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+      if test "x${RESLIB}" != "x-lresolv"; then
+      RESLIB="${RESLIB} -lresolv"
+    fi
+  
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for res_mkquery in -lbind""... $ac_c" 1>&6
+echo "configure:1164: checking for res_mkquery in -lbind" >&5
+ac_lib_var=`echo bind'_'res_mkquery | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lbind  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1172 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char res_mkquery();
+
+int main() {
+res_mkquery()
+; return 0; }
+EOF
+if { (eval echo configure:1183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+        if test "x${RESLIB}" != "x-lbind"; then
+        RESLIB="${RESLIB} -lbind"
+      fi
+    
+else
+  echo "$ac_t""no" 1>&6
+      dns_reslib_avail="false";
+    
+fi
+
+  
+fi
+
+
+fi
+
+
+if test "${dns_reslib_avail}" = false; then
+dns_reslib_avail="true" 
+echo $ac_n "checking for __res_mkquery""... $ac_c" 1>&6
+echo "configure:1218: checking for __res_mkquery" >&5
+if eval "test \"`echo '$''{'ac_cv_func___res_mkquery'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1223 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char __res_mkquery(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char __res_mkquery();
+
+int main() {
+
+/* 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___res_mkquery) || defined (__stub_____res_mkquery)
+choke me
+#else
+__res_mkquery();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1246: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func___res_mkquery=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func___res_mkquery=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'__res_mkquery`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for __res_mkquery in -lresolv""... $ac_c" 1>&6
+echo "configure:1264: checking for __res_mkquery in -lresolv" >&5
+ac_lib_var=`echo resolv'_'__res_mkquery | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lresolv  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1272 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char __res_mkquery();
+
+int main() {
+__res_mkquery()
+; return 0; }
+EOF
+if { (eval echo configure:1283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+      if test "x${RESLIB}" != "x-lresolv"; then
+      RESLIB="${RESLIB} -lresolv"
+    fi
+  
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for __res_mkquery in -lbind""... $ac_c" 1>&6
+echo "configure:1305: checking for __res_mkquery in -lbind" >&5
+ac_lib_var=`echo bind'_'__res_mkquery | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lbind  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1313 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char __res_mkquery();
+
+int main() {
+__res_mkquery()
+; return 0; }
+EOF
+if { (eval echo configure:1324: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+        if test "x${RESLIB}" != "x-lbind"; then
+        RESLIB="${RESLIB} -lbind"
+      fi
+    
+else
+  echo "$ac_t""no" 1>&6
+      dns_reslib_avail="false";
+    
+fi
+
+  
+fi
+
+
+fi
+
+fi
+
+if test "$ac_cv_cygwin" = "yes"
+then
+  echo $ac_n "checking for /usr/local/bind/lib/libbind.a""... $ac_c" 1>&6
+echo "configure:1360: checking for /usr/local/bind/lib/libbind.a" >&5
+  if test -r /usr/local/bind/lib/libbind.a
+  then
+    echo "$ac_t""yes" 1>&6
+    RESLIB="${RESLIB} /usr/local/bind/lib/libbind.a"
+    RESINCLUDE="-I/usr/local/bind/include"
+    dns_reslib_avail="true" 
+  else
+    echo "$ac_t""no" 1>&6
+  fi
+fi
+
+if test "${dns_reslib_avail}" = false; then
+  cat >&2 <<EOF
+configure: warning:
+
+  Your system provides no functional resolver library. The DNS
+  module will therefore be disabled.
+
+EOF
+  ${srcdir}/../../../misc/modconfig -q --top_srcdir=${srcdir}/../../.. --bindir=../../.. del dns
+fi
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# 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.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# 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.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ 	`~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@RESLIB@%$RESLIB%g
+s%@RESINCLUDE@%$RESINCLUDE%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+

+ 102 - 0
src/mod/dns.mod/configure.in

@@ -0,0 +1,102 @@
+dnl Eggdrop compile-time configuration file for src/mod/dns.mod
+dnl
+dnl $Id: configure.in,v 1.7 2001/07/24 15:08:22 guppy Exp $
+
+dnl This file is based on the autoconf m4 macros. Special eggdrop
+dnl macros are used to optimise the size of the resulting configure
+dnl script `./configure'.  Run `../eggautoconf' to update that
+dnl script. You need to have the GNU autoconf package installed
+dnl though.
+
+
+dnl Instead of AC_INIT, we call EGG_INIT().
+sinclude(../eggmod.m4)
+EGG_INIT(coredns.c)
+
+
+AC_PROG_CC
+AC_CYGWIN
+
+dns_reslib_avail="true"
+AC_CHECK_FUNC(res_init, ,
+  AC_CHECK_LIB(resolv, res_init, RESLIB="-lresolv",
+    AC_CHECK_LIB(bind, res_init, RESLIB="-lbind", [dnl
+      dns_reslib_avail="false";
+    ])dnl
+  )dnl
+)dnl
+
+if test "${dns_reslib_avail}" = false; then
+  dns_reslib_avail="true"
+  AC_CHECK_FUNC(__res_init, ,
+    AC_CHECK_LIB(resolv, __res_init, RESLIB="-lresolv",
+      AC_CHECK_LIB(bind, __res_init, RESLIB="-lbind", [dnl
+        dns_reslib_avail="false";
+      ])dnl
+    )dnl
+  )dnl
+fi
+
+AC_CHECK_FUNC(res_mkquery, ,
+  AC_CHECK_LIB(resolv, res_mkquery, [dnl
+    if test "x${RESLIB}" != "x-lresolv"; then
+      RESLIB="${RESLIB} -lresolv"
+    fi
+  ],
+    AC_CHECK_LIB(bind, res_mkquery, [dnl
+      if test "x${RESLIB}" != "x-lbind"; then
+        RESLIB="${RESLIB} -lbind"
+      fi
+    ], [dnl
+      dns_reslib_avail="false";
+    ])
+  )
+)
+
+if test "${dns_reslib_avail}" = false; then
+dns_reslib_avail="true" 
+AC_CHECK_FUNC(__res_mkquery, ,
+  AC_CHECK_LIB(resolv, __res_mkquery, [dnl
+    if test "x${RESLIB}" != "x-lresolv"; then
+      RESLIB="${RESLIB} -lresolv"
+    fi
+  ],
+    AC_CHECK_LIB(bind, __res_mkquery, [dnl
+      if test "x${RESLIB}" != "x-lbind"; then
+        RESLIB="${RESLIB} -lbind"
+      fi
+    ], [dnl
+      dns_reslib_avail="false";
+    ])
+  )
+)
+fi
+
+if test "$ac_cv_cygwin" = "yes"
+then
+  AC_MSG_CHECKING(for /usr/local/bind/lib/libbind.a)
+  if test -r /usr/local/bind/lib/libbind.a
+  then
+    AC_MSG_RESULT(yes)
+    RESLIB="${RESLIB} /usr/local/bind/lib/libbind.a"
+    RESINCLUDE="-I/usr/local/bind/include"
+    dns_reslib_avail="true" 
+  else
+    AC_MSG_RESULT(no)
+  fi
+fi
+
+if test "${dns_reslib_avail}" = false; then
+  cat >&2 <<EOF
+configure: warning:
+
+  Your system provides no functional resolver library. The DNS
+  module will therefore be disabled.
+
+EOF
+  EGG_REMOVE_MOD(dns)
+fi
+AC_SUBST(RESLIB)
+AC_SUBST(RESINCLUDE)
+
+AC_OUTPUT(Makefile)

+ 1129 - 0
src/mod/dns.mod/coredns.c

@@ -0,0 +1,1129 @@
+/*
+ * dnscore.c -- part of dns.mod
+ *   This file contains all core functions needed for the eggdrop dns module.
+ *   Many of them are only minimaly modified from the original source.
+ *
+ * Modified/written by Fabian Knittel <fknittel@gmx.de>
+ *
+ * $Id: coredns.c,v 1.21 2002/01/02 03:46:38 guppy Exp $
+ */
+/*
+ * Portions Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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.
+ */
+
+/*
+ * Borrowed from mtr  --  a network diagnostic tool
+ * Copyright (C) 1997,1998  Matt Kimball <mkimball@xmission.com>
+ * Released under the GPL, as above.
+ *
+ * Non-blocking DNS portion --
+ * Copyright (C) 1998  Simon Kirby <sim@neato.org>
+ * Released under the GPL, as above.
+ */
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <errno.h>
+
+
+/* Defines */
+
+#define BASH_SIZE	 8192		/* Size of hash tables */
+#define HOSTNAMELEN 	  255		/* From RFC */
+#define RES_RETRYDELAY      3
+#define RES_MAXSENDS        4
+#define RES_FAILEDDELAY   600		/* TTL for failed records (in
+					   seconds). */
+#define RES_MAX_TTL     86400		/* Maximum TTL (in seconds). */
+
+#define RES_ERR "DNS Resolver error: "
+#define RES_MSG "DNS Resolver: "
+#define RES_WRN "DNS Resolver warning: "
+
+#define MAX_PACKETSIZE (PACKETSZ)
+#define MAX_DOMAINLEN (MAXDNAME)
+
+/* Macros */
+
+#define nonull(s) (s) ? s : nullstring
+#define BASH_MODULO(x) ((x) & 8191)	/* Modulo for hash table size */
+
+/* Non-blocking nameserver interface routines */
+
+#ifdef DEBUG_DNS
+#  define RESPONSECODES_COUNT 6
+static char *responsecodes[RESPONSECODES_COUNT + 1] = {
+    "no error",
+    "format error in query",
+    "server failure",
+    "queried domain name does not exist",
+    "requested query type not implemented",
+    "refused by name server",
+    "unknown error",
+};
+#endif /* DEBUG_DNS */
+
+#ifdef DEBUG_DNS
+#  define RESOURCETYPES_COUNT 17
+static const char *resourcetypes[RESOURCETYPES_COUNT + 1] = {
+    "unknown type",
+    "A: host address",
+    "NS: authoritative name server",
+    "MD: mail destination (OBSOLETE)",
+    "MF: mail forwarder (OBSOLETE)",
+    "CNAME: name alias",
+    "SOA: authority record",
+    "MB: mailbox domain name (EXPERIMENTAL)",
+    "MG: mail group member (EXPERIMENTAL)",
+    "MR: mail rename domain name (EXPERIMENTAL)",
+    "NULL: NULL RR (EXPERIMENTAL)",
+    "WKS: well known service description",
+    "PTR: domain name pointer",
+    "HINFO: host information",
+    "MINFO: mailbox or mail list information",
+    "MX: mail exchange",
+    "TXT: text string",
+    "unknown type",
+};
+#endif /* DEBUG_DNS */
+
+#ifdef DEBUG_DNS
+#  define CLASSTYPES_COUNT 5
+static const char *classtypes[CLASSTYPES_COUNT + 1] = {
+    "unknown class",
+    "IN: the Internet",
+    "CS: CSNET (OBSOLETE)",
+    "CH: CHAOS",
+    "HS: Hesoid [Dyer 87]",
+    "unknown class"
+};
+#endif /* DEBUG_DNS */
+
+typedef struct {
+    u_16bit_t	id;			/* Packet id */
+    u_8bit_t	databyte_a;
+    /* rd:1				recursion desired
+     * tc:1				truncated message
+     * aa:1				authoritive answer
+     * opcode:4				purpose of message
+     * qr:1				response flag
+     */
+    u_8bit_t	databyte_b;
+    /* rcode:4				response code
+     * unassigned:2			unassigned bits
+     * pr:1				primary server required (non standard)
+     * ra:1				recursion available
+     */
+    u_16bit_t	qdcount;		/* Query record count */
+    u_16bit_t	ancount;		/* Answer record count */
+    u_16bit_t	nscount;		/* Authority reference record count */
+    u_16bit_t	arcount;		/* Resource reference record count */
+} packetheader;
+
+#ifndef HFIXEDSZ
+#define HFIXEDSZ (sizeof(packetheader))
+#endif
+
+/*
+ * Byte order independent macros for packetheader
+ */
+#define getheader_rd(x) (x->databyte_a & 1)
+#define getheader_tc(x) ((x->databyte_a >> 1) & 1)
+#define getheader_aa(x) ((x->databyte_a >> 2) & 1)
+#define getheader_opcode(x) ((x->databyte_a >> 3) & 15)
+#define getheader_qr(x) (x->databyte_a >> 7)
+#define getheader_rcode(x) (x->databyte_b & 15)
+#define getheader_pr(x) ((x->databyte_b >> 6) & 1)
+#define getheader_ra(x) (x->databyte_b >> 7)
+
+#define sucknetword(x)  ((x)+=2,((u_16bit_t)  (((x)[-2] <<  8) | ((x)[-1] <<  0))))
+#define sucknetshort(x) ((x)+=2,((short) (((x)[-2] <<  8) | ((x)[-1] <<  0))))
+#define sucknetdword(x) ((x)+=4,((dword) (((x)[-4] << 24) | ((x)[-3] << 16) | \
+                                          ((x)[-2] <<  8) | ((x)[-1] <<  0))))
+#define sucknetlong(x)  ((x)+=4,((long)  (((x)[-4] << 24) | ((x)[-3] << 16) | \
+                                          ((x)[-2] <<  8) | ((x)[-1] <<  0))))
+
+
+static u_32bit_t resrecvbuf[(MAX_PACKETSIZE + 7) >> 2];	/* MUST BE DWORD ALIGNED */
+
+static struct resolve *idbash[BASH_SIZE];
+static struct resolve *ipbash[BASH_SIZE];
+static struct resolve *hostbash[BASH_SIZE];
+static struct resolve *expireresolves = NULL;
+
+static IP localhost;
+
+static long idseed = 0xdeadbeef;
+static long aseed;
+
+static int resfd;
+
+static char tempstring[512];
+static char namestring[1024 + 1];
+static char stackstring[1024 + 1];
+
+#ifdef DEBUG_DNS
+static char sendstring[1024 + 1];
+#endif /* DEBUG_DNS */
+
+static const char nullstring[] = "";
+
+
+/*
+ *    Miscellaneous helper functions
+ */
+
+#ifdef DEBUG_DNS
+/* Displays the time difference passed in signeddiff.
+ */
+static char *strtdiff(char *d, long signeddiff)
+{
+    u_32bit_t diff;
+    u_32bit_t seconds, minutes, hours;
+    long day;
+
+    if ((diff = labs(signeddiff))) {
+	seconds = diff % 60;
+	diff /= 60;
+	minutes = diff % 60;
+	diff /= 60;
+	hours = diff % 24;
+	day = signeddiff / (60 * 60 * 24);
+	if (day)
+	    sprintf(d, "%lid", day);
+	else
+	    *d = '\0';
+	if (hours)
+	    sprintf(d + strlen(d), "%uh", hours);
+	if (minutes)
+	    sprintf(d + strlen(d), "%um", minutes);
+	if (seconds)
+	    sprintf(d + strlen(d), "%us", seconds);
+    } else
+	sprintf(d, "0s");
+    return d;
+}
+#endif /* DEBUG_DNS */
+
+/* Allocate memory to hold one resolve request structure.
+ */
+static struct resolve *allocresolve()
+{
+    struct resolve *rp;
+
+    rp = (struct resolve *) nmalloc(sizeof(struct resolve));
+    egg_bzero(rp, sizeof(struct resolve));
+    return rp;
+}
+
+
+/*
+ *    Hash and linked-list related functions
+ */
+
+/* Return the hash bucket number for id.
+ */
+inline static u_32bit_t getidbash(u_16bit_t id)
+{
+    return (u_32bit_t) BASH_MODULO(id);
+}
+
+/* Return the hash bucket number for ip.
+ */
+inline static u_32bit_t getipbash(IP ip)
+{
+    return (u_32bit_t) BASH_MODULO(ip);
+}
+
+/* Return the hash bucket number for host.
+ */
+static u_32bit_t gethostbash(char *host)
+{
+    u_32bit_t bashvalue = 0;
+
+    for (; *host; host++) {
+	bashvalue ^= *host;
+	bashvalue += (*host >> 1) + (bashvalue >> 1);
+    }
+    return BASH_MODULO(bashvalue);
+}
+
+/* Insert request structure addrp into the id hash table.
+ */
+static void linkresolveid(struct resolve *addrp)
+{
+    struct resolve *rp;
+    u_32bit_t bashnum;
+
+    bashnum = getidbash(addrp->id);
+    rp = idbash[bashnum];
+    if (rp) {
+	while ((rp->nextid) && (addrp->id > rp->nextid->id))
+	    rp = rp->nextid;
+	while ((rp->previousid) && (addrp->id < rp->previousid->id))
+	    rp = rp->previousid;
+	if (rp->id < addrp->id) {
+	    addrp->previousid = rp;
+	    addrp->nextid = rp->nextid;
+	    if (rp->nextid)
+		rp->nextid->previousid = addrp;
+	    rp->nextid = addrp;
+	} else if (rp->id > addrp->id) {
+	    addrp->previousid = rp->previousid;
+	    addrp->nextid = rp;
+	    if (rp->previousid)
+		rp->previousid->nextid = addrp;
+	    rp->previousid = addrp;
+	} else		/* Trying to add the same id! */
+	    return;
+    } else
+	addrp->nextid = addrp->previousid = NULL;
+    idbash[bashnum] = addrp;
+}
+
+/* Remove request structure rp from the id hash table.
+ */
+static void unlinkresolveid(struct resolve *rp)
+{
+    u_32bit_t bashnum;
+
+    bashnum = getidbash(rp->id);
+    if (idbash[bashnum] == rp) {
+	if (rp->previousid)
+	    idbash[bashnum] = rp->previousid;
+	else
+	    idbash[bashnum] = rp->nextid;
+    }
+    if (rp->nextid)
+	rp->nextid->previousid = rp->previousid;
+    if (rp->previousid)
+	rp->previousid->nextid = rp->nextid;
+}
+
+/* Insert request structure addrp into the host hash table.
+ */
+static void linkresolvehost(struct resolve *addrp)
+{
+    struct resolve *rp;
+    u_32bit_t bashnum;
+    int ret;
+
+    bashnum = gethostbash(addrp->hostn);
+    rp = hostbash[bashnum];
+    if (rp) {
+	while ((rp->nexthost) &&
+	       (egg_strcasecmp(addrp->hostn, rp->nexthost->hostn) < 0))
+	    rp = rp->nexthost;
+	while ((rp->previoushost) &&
+	       (egg_strcasecmp(addrp->hostn, rp->previoushost->hostn) > 0))
+	    rp = rp->previoushost;
+	ret = egg_strcasecmp(addrp->hostn, rp->hostn);
+	if (ret < 0) {
+	    addrp->previoushost = rp;
+	    addrp->nexthost = rp->nexthost;
+	    if (rp->nexthost)
+		rp->nexthost->previoushost = addrp;
+	    rp->nexthost = addrp;
+	} else if (ret > 0) {
+	    addrp->previoushost = rp->previoushost;
+	    addrp->nexthost = rp;
+	    if (rp->previoushost)
+		rp->previoushost->nexthost = addrp;
+	    rp->previoushost = addrp;
+	} else		/* Trying to add the same host! */
+	    return;
+    } else
+	addrp->nexthost = addrp->previoushost = NULL;
+    hostbash[bashnum] = addrp;
+}
+
+/* Remove request structure rp from the host hash table.
+ */
+static void unlinkresolvehost(struct resolve *rp)
+{
+    u_32bit_t bashnum;
+
+    bashnum = gethostbash(rp->hostn);
+    if (hostbash[bashnum] == rp) {
+	if (rp->previoushost)
+	    hostbash[bashnum] = rp->previoushost;
+	else
+	    hostbash[bashnum] = rp->nexthost;
+    }
+    if (rp->nexthost)
+	rp->nexthost->previoushost = rp->previoushost;
+    if (rp->previoushost)
+	rp->previoushost->nexthost = rp->nexthost;
+    nfree(rp->hostn);
+}
+
+/* Insert request structure addrp into the ip hash table.
+ */
+static void linkresolveip(struct resolve *addrp)
+{
+    struct resolve *rp;
+    u_32bit_t bashnum;
+
+    bashnum = getipbash(addrp->ip);
+    rp = ipbash[bashnum];
+    if (rp) {
+	while ((rp->nextip) && (addrp->ip > rp->nextip->ip))
+	    rp = rp->nextip;
+	while ((rp->previousip) && (addrp->ip < rp->previousip->ip))
+	    rp = rp->previousip;
+	if (rp->ip < addrp->ip) {
+	    addrp->previousip = rp;
+	    addrp->nextip = rp->nextip;
+	    if (rp->nextip)
+		rp->nextip->previousip = addrp;
+	    rp->nextip = addrp;
+	} else if (rp->ip > addrp->ip) {
+	    addrp->previousip = rp->previousip;
+	    addrp->nextip = rp;
+	    if (rp->previousip)
+		rp->previousip->nextip = addrp;
+	    rp->previousip = addrp;
+	} else		/* Trying to add the same ip! */
+	    return;
+    } else
+	addrp->nextip = addrp->previousip = NULL;
+    ipbash[bashnum] = addrp;
+}
+
+/* Remove request structure rp from the ip hash table.
+ */
+static void unlinkresolveip(struct resolve *rp)
+{
+    u_32bit_t bashnum;
+
+    bashnum = getipbash(rp->ip);
+    if (ipbash[bashnum] == rp) {
+	if (rp->previousip)
+	    ipbash[bashnum] = rp->previousip;
+	else
+	    ipbash[bashnum] = rp->nextip;
+    }
+    if (rp->nextip)
+	rp->nextip->previousip = rp->previousip;
+    if (rp->previousip)
+	rp->previousip->nextip = rp->nextip;
+}
+
+/* Add request structure rp to the expireresolves list. Entries are sorted
+ * by expire time.
+ */
+static void linkresolve(struct resolve *rp)
+{
+    struct resolve *irp;
+
+    if (expireresolves) {
+	irp = expireresolves;
+	while ((irp->next) && (rp->expiretime >= irp->expiretime))
+	    irp = irp->next;
+	if (rp->expiretime >= irp->expiretime) {
+	    rp->next = NULL;
+	    rp->previous = irp;
+	    irp->next = rp;
+	} else {
+	    rp->previous = irp->previous;
+	    rp->next = irp;
+	    if (irp->previous)
+		irp->previous->next = rp;
+	    else
+		expireresolves = rp;
+	    irp->previous = rp;
+	}
+    } else {
+	rp->next = NULL;
+	rp->previous = NULL;
+	expireresolves = rp;
+    }
+}
+
+/* Remove reqeust structure rp from the expireresolves list.
+ */
+static void untieresolve(struct resolve *rp)
+{
+    if (rp->previous)
+	rp->previous->next = rp->next;
+    else
+	expireresolves = rp->next;
+    if (rp->next)
+	rp->next->previous = rp->previous;
+}
+
+/* Remove request structure rp from all lists and hash tables and
+ * then delete and free the structure
+ */
+static void unlinkresolve(struct resolve *rp)
+{
+
+    untieresolve(rp);		/* Not really needed. Left in to be on the
+				   safe side. */
+    unlinkresolveid(rp);
+    unlinkresolveip(rp);
+    if (rp->hostn)
+	unlinkresolvehost(rp);
+    nfree(rp);
+}
+
+/* Find request structure using the id.
+ */
+static struct resolve *findid(u_16bit_t id)
+{
+    struct resolve *rp;
+    int bashnum;
+
+    bashnum = getidbash(id);
+    rp = idbash[bashnum];
+    if (rp) {
+	while ((rp->nextid) && (id >= rp->nextid->id))
+	    rp = rp->nextid;
+	while ((rp->previousid) && (id <= rp->previousid->id))
+	    rp = rp->previousid;
+	if (id == rp->id) {
+	    idbash[bashnum] = rp;
+	    return rp;
+	} else
+	    return NULL;
+    }
+    return rp;			/* NULL */
+}
+
+/* Find request structure using the host.
+ */
+static struct resolve *findhost(char *hostn)
+{
+    struct resolve *rp;
+    int bashnum;
+
+    bashnum = gethostbash(hostn);
+    rp = hostbash[bashnum];
+    if (rp) {
+	while ((rp->nexthost)
+	       && (egg_strcasecmp(hostn, rp->nexthost->hostn) >= 0))
+	    rp = rp->nexthost;
+	while ((rp->previoushost)
+	       && (egg_strcasecmp(hostn, rp->previoushost->hostn) <= 0))
+	    rp = rp->previoushost;
+	if (egg_strcasecmp(hostn, rp->hostn))
+	    return NULL;
+	else {
+	    hostbash[bashnum] = rp;
+	    return rp;
+	}
+    }
+    return rp;			/* NULL */
+}
+
+/* Find request structure using the ip.
+ */
+static struct resolve *findip(IP ip)
+{
+    struct resolve *rp;
+    u_32bit_t bashnum;
+
+    bashnum = getipbash(ip);
+    rp = ipbash[bashnum];
+    if (rp) {
+	while ((rp->nextip) && (ip >= rp->nextip->ip))
+	    rp = rp->nextip;
+	while ((rp->previousip) && (ip <= rp->previousip->ip))
+	    rp = rp->previousip;
+	if (ip == rp->ip) {
+	    ipbash[bashnum] = rp;
+	    return rp;
+	} else
+	    return NULL;
+    }
+    return rp;			/* NULL */
+}
+
+
+/*
+ *    Network and resolver related functions
+ */
+
+/* Create packet for the request and send it to all available nameservers.
+ */
+static void dorequest(char *s, int type, u_16bit_t id)
+{
+    packetheader *hp;
+    int r, i;
+    u_8bit_t buf[(MAX_PACKETSIZE / sizeof(char)) + 1];
+
+    r = res_mkquery(QUERY, s, C_IN, type, NULL, 0, NULL, buf,
+		    MAX_PACKETSIZE);
+    if (r == -1) {
+	ddebug0(RES_ERR "Query too large.");
+	return;
+    }
+    hp = (packetheader *) buf;
+    hp->id = id;	/* htons() deliberately left out (redundant) */
+    for (i = 0; i < _res.nscount; i++)
+	(void) sendto(resfd, buf, r, 0,
+		      (struct sockaddr *) &_res.nsaddr_list[i],
+		      sizeof(struct sockaddr));
+}
+
+/* (Re-)send request with existing id.
+ */
+static void resendrequest(struct resolve *rp, int type)
+{
+    rp->sends++;
+    /* Update expire time */
+    rp->expiretime = now + (RES_RETRYDELAY * rp->sends);
+    /* Add (back) to expire list */
+    linkresolve(rp);
+
+    if (type == T_A) {
+	dorequest(rp->hostn, type, rp->id);
+	ddebug1(RES_MSG "Sent domain lookup request for \"%s\".",
+		rp->hostn);
+    } else if (type == T_PTR) {
+	sprintf(tempstring, "%u.%u.%u.%u.in-addr.arpa",
+		((u_8bit_t *) & rp->ip)[3],
+		((u_8bit_t *) & rp->ip)[2],
+		((u_8bit_t *) & rp->ip)[1], ((u_8bit_t *) & rp->ip)[0]);
+	dorequest(tempstring, type, rp->id);
+	ddebug1(RES_MSG "Sent domain lookup request for \"%s\".",
+		iptostr(rp->ip));
+    }
+}
+
+/* Send request for the first time.
+ */
+static void sendrequest(struct resolve *rp, int type)
+{
+    /* Create unique id */
+    do {
+	idseed = (((idseed + idseed) | (long) time(NULL))
+		  + idseed - 0x54bad4a) ^ aseed;
+	aseed ^= idseed;
+	rp->id = (u_16bit_t) idseed;
+    } while (findid(rp->id));
+    linkresolveid(rp);		/* Add id to id hash table */
+    resendrequest(rp, type);	/* Send request */
+}
+
+/* Gets called as soon as the request turns out to have failed. Calls
+ * the eggdrop hook.
+ */
+static void failrp(struct resolve *rp, int type)
+{
+    if (rp->state == STATE_FINISHED)
+	return;
+    rp->expiretime = now + RES_FAILEDDELAY;
+    rp->state = STATE_FAILED;
+
+    /* Expire time was changed, reinsert entry to maintain order */
+    untieresolve(rp);
+    linkresolve(rp);
+
+    ddebug0(RES_MSG "Lookup failed.");
+    dns_event_failure(rp, type);
+}
+
+/* Gets called as soon as the request turns out to be successful. Calls
+ * the eggdrop hook.
+ */
+static void passrp(struct resolve *rp, long ttl, int type)
+{
+    rp->state = STATE_FINISHED;
+
+    /* Do not cache entries for too long. */
+    if (ttl < RES_MAX_TTL)
+	rp->expiretime = now + (time_t) ttl;
+    else
+	rp->expiretime = now + RES_MAX_TTL;
+
+    /* Expire time was changed, reinsert entry to maintain order */
+    untieresolve(rp);
+    linkresolve(rp);
+
+    ddebug1(RES_MSG "Lookup successful: %s", rp->hostn);
+    dns_event_success(rp, type);
+}
+
+/* Parses the response packets received.
+ */
+static void parserespacket(u_8bit_t *s, int l)
+{
+    struct resolve *rp;
+    packetheader *hp;
+    u_8bit_t *eob;
+    u_8bit_t *c;
+    long ttl;
+    int r, usefulanswer;
+    u_16bit_t rr, datatype, class, qdatatype, qclass;
+    u_8bit_t rdatalength;
+
+    if (l < sizeof(packetheader)) {
+	debug0(RES_ERR "Packet smaller than standard header size.");
+	return;
+    }
+    if (l == sizeof(packetheader)) {
+	debug0(RES_ERR "Packet has empty body.");
+	return;
+    }
+    hp = (packetheader *) s;
+    /* Convert data to host byte order
+     *
+     * hp->id does not need to be redundantly byte-order flipped, it
+     * is only echoed by nameserver
+     */
+    rp = findid(hp->id);
+    if (!rp)
+	return;
+    if ((rp->state == STATE_FINISHED) || (rp->state == STATE_FAILED))
+	return;
+    hp->qdcount = ntohs(hp->qdcount);
+    hp->ancount = ntohs(hp->ancount);
+    hp->nscount = ntohs(hp->nscount);
+    hp->arcount = ntohs(hp->arcount);
+    if (getheader_tc(hp)) {	/* Packet truncated */
+	ddebug0(RES_ERR "Nameserver packet truncated.");
+	return;
+    }
+    if (!getheader_qr(hp)) {	/* Not a reply */
+	ddebug0(RES_ERR "Query packet received on nameserver communication socket.");
+	return;
+    }
+    if (getheader_opcode(hp)) {	/* Not opcode 0 (standard query) */
+	ddebug0(RES_ERR "Invalid opcode in response packet.");
+	return;
+    }
+    eob = s + l;
+    c = s + HFIXEDSZ;
+    switch (getheader_rcode(hp)) {
+    case NOERROR:
+	if (hp->ancount) {
+	    ddebug4(RES_MSG
+		    "Received nameserver reply. (qd:%u an:%u ns:%u ar:%u)",
+		    hp->qdcount, hp->ancount, hp->nscount, hp->arcount);
+	    if (hp->qdcount != 1) {
+		ddebug0(RES_ERR "Reply does not contain one query.");
+		return;
+	    }
+	    if (c > eob) {
+		ddebug0(RES_ERR "Reply too short.");
+		return;
+	    }
+	    switch (rp->state) {	/* Construct expected query reply */
+	    case STATE_PTRREQ:
+		sprintf(stackstring,
+			"%u.%u.%u.%u.in-addr.arpa",
+			((u_8bit_t *) & rp->ip)[3],
+			((u_8bit_t *) & rp->ip)[2],
+			((u_8bit_t *) & rp->ip)[1], ((u_8bit_t *) & rp->ip)[0]);
+		break;
+	    case STATE_AREQ:
+		strncpy(stackstring, rp->hostn, 1024);
+	    }
+	    *namestring = '\0';
+	    r = dn_expand(s, s + l, c, namestring, MAXDNAME);
+	    if (r == -1) {
+		ddebug0(RES_ERR "dn_expand() failed while expanding query domain.");
+		return;
+	    }
+	    namestring[strlen(stackstring)] = '\0';
+	    if (egg_strcasecmp(stackstring, namestring)) {
+		ddebug2(RES_MSG "Unknown query packet dropped. (\"%s\" does not match \"%s\")", stackstring, namestring);
+		return;
+	    }
+	    ddebug1(RES_MSG "Queried domain name: \"%s\"", namestring);
+	    c += r;
+	    if (c + 4 > eob) {
+		ddebug0(RES_ERR "Query resource record truncated.");
+		return;
+	    }
+	    qdatatype = sucknetword(c);
+	    qclass = sucknetword(c);
+	    if (qclass != C_IN) {
+		ddebug2(RES_ERR "Received unsupported query class: %u (%s)",
+			qclass, qclass < CLASSTYPES_COUNT ?
+					classtypes[qclass] :
+					classtypes[CLASSTYPES_COUNT]);
+	    }
+	    switch (qdatatype) {
+	    case T_PTR:
+		if (!IS_PTR(rp)) {
+		    ddebug0(RES_WRN "Ignoring response with unexpected query type \"PTR\".");
+		    return;
+		}
+		break;
+	    case T_A:
+		if (!IS_A(rp)) {
+		    ddebug0(RES_WRN "Ignoring response with unexpected query type \"PTR\".");
+		    return;
+		}
+		break;
+	    default:
+		ddebug2(RES_ERR "Received unimplemented query type: %u (%s)",
+			qdatatype,
+			qdatatype < RESOURCETYPES_COUNT ?
+				resourcetypes[qdatatype] :
+				resourcetypes[RESOURCETYPES_COUNT]);
+	    }
+	    for (rr = hp->ancount + hp->nscount + hp->arcount; rr; rr--) {
+		if (c > eob) {
+		    ddebug0(RES_ERR "Packet does not contain all specified resouce records.");
+		    return;
+		}
+		*namestring = '\0';
+		r = dn_expand(s, s + l, c, namestring, MAXDNAME);
+		if (r == -1) {
+		    ddebug0(RES_ERR "dn_expand() failed while expanding answer domain.");
+		    return;
+		}
+		namestring[strlen(stackstring)] = '\0';
+		if (egg_strcasecmp(stackstring, namestring))
+		    usefulanswer = 0;
+		else
+		    usefulanswer = 1;
+		ddebug1(RES_MSG "answered domain query: \"%s\"", namestring);
+		c += r;
+		if (c + 10 > eob) {
+		    ddebug0(RES_ERR "Resource record truncated.");
+		    return;
+		}
+		datatype = sucknetword(c);
+		class = sucknetword(c);
+		ttl = sucknetlong(c);
+		rdatalength = sucknetword(c);
+		if (class != qclass) {
+		    ddebug2(RES_MSG "query class: %u (%s)",
+			    qclass,
+			    qclass < CLASSTYPES_COUNT ?
+				classtypes[qclass] :
+				classtypes[CLASSTYPES_COUNT]);
+		    ddebug2(RES_MSG "rr class: %u (%s)", class,
+			    class < CLASSTYPES_COUNT ?
+				classtypes[class] :
+				classtypes[CLASSTYPES_COUNT]);
+		    ddebug0(RES_ERR "Answered class does not match queried class.");
+		    return;
+		}
+		if (!rdatalength) {
+		    ddebug0(RES_ERR "Zero size rdata.");
+		    return;
+		}
+		if (c + rdatalength > eob) {
+		    ddebug0(RES_ERR "Specified rdata length exceeds packet size.");
+		    return;
+		}
+		if (datatype == qdatatype) {
+		    ddebug1(RES_MSG "TTL: %s", strtdiff(sendstring, ttl));
+		    ddebug1(RES_MSG "TYPE: %s", datatype < RESOURCETYPES_COUNT ?
+			    resourcetypes[datatype] :
+			    resourcetypes[RESOURCETYPES_COUNT]);
+		    if (usefulanswer)
+			switch (datatype) {
+			case T_A:
+			    if (rdatalength != 4) {
+				ddebug1(RES_ERR "Unsupported rdata format for \"A\" type. (%u bytes)", rdatalength);
+				return;
+			    }
+			    my_memcpy(&rp->ip, (IP *) c, sizeof(IP));
+			    linkresolveip(rp);
+			    passrp(rp, ttl, T_A);
+			    return;
+			case T_PTR:
+			    *namestring = '\0';
+			    r =	dn_expand(s, s + l, c, namestring, MAXDNAME);
+			    if (r == -1) {
+				ddebug0(RES_ERR "dn_expand() failed while expanding domain in rdata.");
+				return;
+			    }
+			    ddebug1(RES_MSG "Answered domain: \"%s\"",
+				   namestring);
+			    if (r > HOSTNAMELEN) {
+				ddebug0(RES_ERR "Domain name too long.");
+				failrp(rp, T_PTR);
+				return;
+			    }
+			    if (!rp->hostn) {
+				rp->hostn = (char *)nmalloc(strlen(namestring) + 1);
+				strcpy(rp->hostn, namestring);
+				linkresolvehost(rp);
+				passrp(rp, ttl, T_PTR);
+				return;
+			    }
+			    break;
+			default:
+			    ddebug2(RES_ERR "Received unimplemented data type: %u (%s)",
+				    datatype,
+				    datatype < RESOURCETYPES_COUNT ?
+					resourcetypes[datatype] :
+					resourcetypes[RESOURCETYPES_COUNT]);
+			}
+		} else if (datatype == T_CNAME) {
+		    *namestring = '\0';
+		    r =	dn_expand(s, s + l, c, namestring, MAXDNAME);
+		    if (r == -1) {
+			ddebug0(RES_ERR "dn_expand() failed while expanding domain in rdata.");
+			return;
+		    }
+		    ddebug1(RES_MSG "answered domain is CNAME for: %s",
+			   namestring);
+		    /* The next responses will be related to the domain
+		     * pointed to by CNAME, so we need to update which
+		     * respones we regard as important.
+		     */
+		    strncpy(stackstring, namestring, 1024);
+		} else {
+		    ddebug2(RES_MSG "Ignoring resource type %u. (%s)",
+			   datatype, datatype < RESOURCETYPES_COUNT ?
+				resourcetypes[datatype] :
+				resourcetypes[RESOURCETYPES_COUNT]);
+		}
+		c += rdatalength;
+	    }
+	} else
+	    ddebug0(RES_ERR "No error returned but no answers given.");
+	break;
+    case NXDOMAIN:
+	ddebug0(RES_MSG "Host not found.");
+	switch (rp->state) {
+	case STATE_PTRREQ:
+		failrp(rp, T_PTR);
+		break;
+	case STATE_AREQ:
+		failrp(rp, T_A);
+		break;
+	default:
+		failrp(rp, 0);
+		break;
+	}
+	break;
+    default:
+	ddebug2(RES_MSG "Received error response %u. (%s)",
+		getheader_rcode(hp),
+		getheader_rcode(hp) < RESPONSECODES_COUNT ?
+			responsecodes[getheader_rcode(hp)] :
+			responsecodes[RESPONSECODES_COUNT]);
+    }
+}
+
+/* Read data received on our dns socket. This function is called
+ * as soon as traffic is detected.
+ */
+static void dns_ack(void)
+{
+    struct sockaddr_in from;
+    unsigned int fromlen = sizeof(struct sockaddr_in);
+    int r, i;
+
+    r =	recvfrom(resfd, (u_8bit_t *) resrecvbuf, MAX_PACKETSIZE, 0,
+		 (struct sockaddr *) &from, &fromlen);
+    if (r <= 0) {
+	ddebug1(RES_MSG "Socket error: %s", strerror(errno));
+	return;
+    }
+    /* Check to see if this server is actually one we sent to */
+    if (from.sin_addr.s_addr == localhost) {
+        for (i = 0; i < _res.nscount; i++)
+	    /* 0.0.0.0 replies as 127.0.0.1 */
+	    if ((_res.nsaddr_list[i].sin_addr.s_addr == from.sin_addr.s_addr)
+		|| (!_res.nsaddr_list[i].sin_addr.s_addr))
+		break;
+    } else {
+        for (i = 0; i < _res.nscount; i++)
+	    if (_res.nsaddr_list[i].sin_addr.s_addr == from.sin_addr.s_addr)
+		break;
+    }
+    if (i == _res.nscount) {
+        ddebug1(RES_ERR "Received reply from unknown source: %s",
+	       iptostr(from.sin_addr.s_addr));
+    } else
+        parserespacket((u_8bit_t *) resrecvbuf, r);
+}
+
+/* Remove or resend expired requests. Called once a second.
+ */
+static void dns_check_expires(void)
+{
+    struct resolve *rp, *nextrp;
+
+    /* Walk through sorted list ... */
+    for (rp = expireresolves; (rp) && (now >= rp->expiretime);
+	 rp = nextrp) {
+	nextrp = rp->next;
+	untieresolve(rp);
+	switch (rp->state) {
+	case STATE_FINISHED:	/* TTL has expired */
+	case STATE_FAILED:	/* Fake TTL has expired */
+	    ddebug4(RES_MSG "Cache record for \"%s\" (%s) has expired. (state: %u)  Marked for expire at: %ld.",
+		   nonull(rp->hostn), iptostr(rp->ip), rp->state,
+		   rp->expiretime);
+	    unlinkresolve(rp);
+	    break;
+	case STATE_PTRREQ:	/* T_PTR send timed out */
+	    if (rp->sends <= RES_MAXSENDS) {
+	      ddebug1(RES_MSG "Resend #%d for \"PTR\" query...", rp->sends - 1);
+	      resendrequest(rp, T_PTR);
+	    } else {
+	      ddebug0(RES_MSG "\"PTR\" query timed out.");
+	      failrp(rp, T_PTR);
+	    }
+	    break;
+	case STATE_AREQ:	/* T_A send timed out */
+	    if (rp->sends <= RES_MAXSENDS) {
+	      ddebug1(RES_MSG "Resend #%d for \"A\" query...", rp->sends - 1);
+	      resendrequest(rp, T_A);
+	    } else {
+	      ddebug0(RES_MSG "\"A\" query timed out.");
+	      failrp(rp, T_A);
+	    }
+	    break;
+	default:		/* Unknown state, let it expire */
+	    ddebug1(RES_WRN "Unknown request state %d. Request expired.",
+		   rp->state);
+	    failrp(rp, 0);
+	}
+    }
+}
+
+/* Start searching for a host-name, using it's ip-address.
+ */
+static void dns_lookup(IP ip)
+{
+    struct resolve *rp;
+
+    ip = htonl(ip);
+    if ((rp = findip(ip))) {
+	if (rp->state == STATE_FINISHED || rp->state == STATE_FAILED) {
+	    if (rp->state == STATE_FINISHED && rp->hostn) {
+		ddebug2(RES_MSG "Used cached record: %s == \"%s\".",
+			    iptostr(ip), rp->hostn);
+		dns_event_success(rp, T_PTR);
+	    } else {
+		ddebug1(RES_MSG "Used failed record: %s == ???", iptostr(ip));
+		dns_event_failure(rp, T_PTR);
+	    }
+	}
+	return;
+    }
+
+    ddebug0(RES_MSG "Creating new record");
+    rp = allocresolve();
+    rp->state = STATE_PTRREQ;
+    rp->sends = 1;
+    rp->ip = ip;
+    linkresolveip(rp);
+    sendrequest(rp, T_PTR);
+}
+
+/* Start searching for an ip-address, using it's host-name.
+ */
+static void dns_forward(char *hostn)
+{
+    struct resolve *rp;
+    struct in_addr inaddr;
+
+    /* Check if someone passed us an IP address as hostname
+     * and return it straight away.
+     */
+    if (egg_inet_aton(hostn, &inaddr)) {
+      call_ipbyhost(hostn, ntohl(inaddr.s_addr), 1);
+      return;
+    }
+    if ((rp = findhost(hostn))) {
+	if (rp->state == STATE_FINISHED || rp->state == STATE_FAILED) {
+	    if (rp->state == STATE_FINISHED && rp->ip) {
+		ddebug2(RES_MSG "Used cached record: %s == \"%s\".", hostn,
+		       iptostr(rp->ip));
+		dns_event_success(rp, T_A);
+	    } else {
+		ddebug1(RES_MSG "Used failed record: %s == ???", hostn);
+		dns_event_failure(rp, T_A);
+	    }
+	}
+	return;
+    }
+    ddebug0(RES_MSG "Creating new record");
+    rp = allocresolve();
+    rp->state = STATE_AREQ;
+    rp->sends = 1;
+    rp->hostn = (char *)nmalloc(strlen(hostn) + 1);
+    strcpy(rp->hostn, hostn);
+    linkresolvehost(rp);
+    sendrequest(rp, T_A);
+}
+
+/* Initialise the network.
+ */
+static int init_dns_network(void)
+{
+    int option;
+    struct in_addr inaddr;
+
+    resfd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (resfd == -1) {
+	putlog(LOG_MISC, "*",
+		"Unable to allocate socket for nameserver communication: %s",
+		strerror(errno));
+	return 0;
+    }
+    (void) allocsock(resfd, SOCK_PASS);
+    option = 1;
+    if (setsockopt(resfd, SOL_SOCKET, SO_BROADCAST, (char *) &option,
+	 sizeof(option))) {
+	putlog(LOG_MISC, "*",
+		"Unable to setsockopt() on nameserver communication socket: %s",
+		strerror(errno));
+	killsock(resfd);
+	return 0;
+    }
+
+    egg_inet_aton("127.0.0.1", &inaddr);
+    localhost = inaddr.s_addr;
+    return 1;
+}
+
+/* Initialise the core dns system, returns 1 if all goes well, 0 if not.
+ */
+static int init_dns_core(void)
+{
+    int i;
+
+    /* Initialise the resolv library. */
+    res_init();
+    if (!_res.nscount) {
+	putlog(LOG_MISC, "*", "No nameservers defined.");
+	return 0;
+    }
+    _res.options |= RES_RECURSE | RES_DEFNAMES | RES_DNSRCH;
+    for (i = 0; i < _res.nscount; i++)
+	_res.nsaddr_list[i].sin_family = AF_INET;
+
+    if (!init_dns_network())
+	return 0;
+
+    /* Initialise the hash tables. */
+    aseed = time(NULL) ^ (time(NULL) << 3) ^ (u_32bit_t) getpid();
+    for (i = 0; i < BASH_SIZE; i++) {
+	idbash[i] = NULL;
+	ipbash[i] = NULL;
+	hostbash[i] = NULL;
+    }
+    expireresolves = NULL;
+    return 1;
+}

+ 226 - 0
src/mod/dns.mod/dns.c

@@ -0,0 +1,226 @@
+/*
+ * dns.c -- part of dns.mod
+ *   domain lookup glue code for eggdrop
+ *
+ * Written by Fabian Knittel <fknittel@gmx.de>
+ *
+ * $Id: dns.c,v 1.27 2002/07/07 22:35:25 guppy Exp $
+ */
+/*
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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.
+ */
+
+#define MODULE_NAME "dns"
+
+#include "src/mod/module.h"
+#include "dns.h"
+
+static void dns_event_success(struct resolve *rp, int type);
+static void dns_event_failure(struct resolve *rp, int type);
+
+
+static Function *global = NULL;
+
+#include "coredns.c"
+
+
+/*
+ *    DNS event related code
+ */
+
+static void dns_event_success(struct resolve *rp, int type)
+{
+  if (!rp)
+    return;
+
+  if (type == T_PTR) {
+    debug2("DNS resolved %s to %s", iptostr(rp->ip), rp->hostn);
+    call_hostbyip(ntohl(rp->ip), rp->hostn, 1);
+  } else if (type == T_A) {
+    debug2("DNS resolved %s to %s", rp->hostn, iptostr(rp->ip));
+    call_ipbyhost(rp->hostn, ntohl(rp->ip), 1);
+  }
+}
+
+static void dns_event_failure(struct resolve *rp, int type)
+{
+  if (!rp)
+    return;
+
+  if (type == T_PTR) {
+    static char s[UHOSTLEN];
+
+    debug1("DNS resolve failed for %s", iptostr(rp->ip));
+    strcpy(s, iptostr(rp->ip));
+    call_hostbyip(ntohl(rp->ip), s, 0);
+  } else if (type == T_A) {
+    debug1("DNS resolve failed for %s", rp->hostn);
+    call_ipbyhost(rp->hostn, 0, 0);
+  } else
+    debug2("DNS resolve failed for unknown %s / %s", iptostr(rp->ip),
+	   nonull(rp->hostn));
+  return;
+}
+
+
+/*
+ *    DNS Socket related code
+ */
+
+static void eof_dns_socket(int idx)
+{
+  putlog(LOG_MISC, "*", "DNS Error: socket closed.");
+  killsock(dcc[idx].sock);
+  /* Try to reopen socket */
+  if (init_dns_network()) {
+    putlog(LOG_MISC, "*", "DNS socket successfully reopened!");
+    dcc[idx].sock = resfd;
+    dcc[idx].timeval = now;
+  } else
+    lostdcc(idx);
+}
+
+static void dns_socket(int idx, char *buf, int len)
+{
+  dns_ack();
+}
+
+static void display_dns_socket(int idx, char *buf)
+{
+  strcpy(buf, "dns   (ready)");
+}
+
+static struct dcc_table DCC_DNS =
+{
+  "DNS",
+  DCT_LISTEN,
+  eof_dns_socket,
+  dns_socket,
+  NULL,
+  NULL,
+  display_dns_socket,
+  NULL,
+  NULL,
+  NULL
+};
+
+
+/*
+ *    DNS module related code
+ */
+
+static void dns_free_cache(void)
+{
+  struct resolve *rp, *rpnext;
+
+  for (rp = expireresolves; rp; rp = rpnext) {
+    rpnext = rp->next;
+    if (rp->hostn)
+      nfree(rp->hostn);
+    nfree(rp);
+  }
+  expireresolves = NULL;
+}
+
+static int dns_cache_expmem(void)
+{
+  struct resolve *rp;
+  int size = 0;
+
+  for (rp = expireresolves; rp; rp = rp->next) {
+    size += sizeof(struct resolve);
+    if (rp->hostn)
+      size += strlen(rp->hostn) + 1;
+  }
+  return size;
+}
+
+static int dns_expmem(void)
+{
+  return dns_cache_expmem();
+}
+
+static int dns_report(int idx, int details)
+{
+  if (details) {
+    dprintf(idx, "    (cache uses %d bytes of memory)\n", dns_cache_expmem());
+    dprintf(idx, "    DNS resolver is active.\n");
+  }
+  return 0;
+}
+
+static char *dns_close()
+{
+  int i;
+
+  del_hook(HOOK_DNS_HOSTBYIP, (Function) dns_lookup);
+  del_hook(HOOK_DNS_IPBYHOST, (Function) dns_forward);
+  del_hook(HOOK_SECONDLY, (Function) dns_check_expires);
+
+  for (i = 0; i < dcc_total; i++) {
+    if (dcc[i].type == &DCC_DNS &&
+	dcc[i].sock == resfd) {
+      killsock(dcc[i].sock);
+      lostdcc(i);
+      break;
+    }
+  }
+
+  dns_free_cache();
+  module_undepend(MODULE_NAME);
+  return NULL;
+}
+
+EXPORT_SCOPE char *dns_start();
+
+static Function dns_table[] =
+{
+  /* 0 - 3 */
+  (Function) dns_start,
+  (Function) dns_close,
+  (Function) dns_expmem,
+  (Function) dns_report,
+  /* 4 - 7 */
+};
+
+char *dns_start(Function *global_funcs)
+{
+  int idx;
+
+  global = global_funcs;
+  module_register(MODULE_NAME, dns_table, 1, 0);
+  if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) {
+    module_undepend(MODULE_NAME);
+    return "This module requires Eggdrop 1.6.0 or later.";
+  }
+
+  idx = new_dcc(&DCC_DNS, 0);
+  if (idx < 0)
+    return "NO MORE DCC CONNECTIONS -- Can't create DNS socket.";
+  if (!init_dns_core()) {
+    lostdcc(idx);
+    return "DNS initialisation failed.";
+  }
+  dcc[idx].sock = resfd;
+  dcc[idx].timeval = now;
+  strcpy(dcc[idx].nick, "(dns)");
+
+  add_hook(HOOK_SECONDLY, (Function) dns_check_expires);
+  add_hook(HOOK_DNS_HOSTBYIP, (Function) dns_lookup);
+  add_hook(HOOK_DNS_IPBYHOST, (Function) dns_forward);
+  return NULL;
+}

+ 81 - 0
src/mod/dns.mod/dns.h

@@ -0,0 +1,81 @@
+/*
+ * dns.h -- part of dns.mod
+ *   dns module header file
+ *
+ * Written by Fabian Knittel <fknittel@gmx.de>
+ *
+ * $Id: dns.h,v 1.9 2002/01/02 03:46:38 guppy Exp $
+ */
+/*
+ * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
+ *
+ * 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.
+ */
+
+/*
+ * Borrowed from mtr  --  a network diagnostic tool
+ * Copyright (C) 1997,1998  Matt Kimball <mkimball@xmission.com>
+ * Released under GPL, as above.
+ *
+ * Non-blocking DNS portion --
+ * Copyright (C) 1998  Simon Kirby <sim@neato.org>
+ * Released under GPL, as above.
+ */
+
+#ifndef _EGG_MOD_DNS_DNS_H
+#define _EGG_MOD_DNS_DNS_H
+
+struct resolve {
+    struct resolve	*next;
+    struct resolve	*previous;
+    struct resolve	*nextid;
+    struct resolve	*previousid;
+    struct resolve	*nextip;
+    struct resolve	*previousip;
+    struct resolve	*nexthost;
+    struct resolve	*previoushost;
+    time_t		expiretime;
+    char		*hostn;
+    IP			ip;
+    u_16bit_t		id;
+    u_8bit_t		state;
+    u_8bit_t		sends;
+};
+
+enum resolve_states {
+    STATE_FINISHED,
+    STATE_FAILED,
+    STATE_PTRREQ,
+    STATE_AREQ
+};
+
+#define IS_PTR(x) (x->state == STATE_PTRREQ)
+#define IS_A(x)   (x->state == STATE_AREQ)
+
+#ifdef DEBUG_DNS
+# define ddebug0		debug0
+# define ddebug1		debug1
+# define ddebug2		debug2
+# define ddebug3		debug3
+# define ddebug4		debug4
+#else	/* !DEBUG_DNS */
+# define ddebug0(x)
+# define ddebug1(x, x1)
+# define ddebug2(x, x1, x2)
+# define ddebug3(x, x1, x2, x3)
+# define ddebug4(x, x1, x2, x3, x4)
+#endif	/* !DEBUG_DNS */
+
+#endif	/* _EGG_MOD_DNS_DNS_H */

+ 36 - 0
src/mod/eggautoconf

@@ -0,0 +1,36 @@
+#! /bin/sh
+#
+# eggautoconf -- creates workable small configure scripts by cutting down
+#                GNU autoconf scripts with the help of special eggdrop
+#                m4 macros.
+#
+# $Id: eggautoconf,v 1.4 2002/01/02 03:46:37 guppy Exp $
+#
+# Copyright (C) 2000, 2001, 2002 Eggheads Development Team
+# Written by Fabian Knittel
+
+set -e
+if test ! -f configure.in; then
+	echo "$0: error: no \`configure.in' found."
+	exit 1
+fi
+if test ! -f ../eggmod.sh; then
+	echo "$0: \`../eggmod.sh' not found. Not calling from module directory?"
+	exit 1
+fi
+autoconf
+if test ! -f configure; then
+	echo "$0: error: autoconf did not produce \`configure' script."
+	exit 1
+fi
+echo "Recreating eggdrop/autoconf configure script."
+if (cat configure | awk '
+	BEGIN { RS = "\f-never-\f"; FS = "\n## SPLIT" }
+	{ print "#! /bin/sh" $2 }' > configure_new); then
+	mv configure_new configure
+	chmod 0775 configure
+else
+	echo "Failed to create configure script!" >&2
+	exit 1
+fi
+exit 0

+ 46 - 0
src/mod/eggmod.m4

@@ -0,0 +1,46 @@
+dnl eggmod.m4
+dnl   macros eggdrop modules should use instead of the original autoconf
+dnl   versions.
+dnl
+dnl $Id: eggmod.m4,v 1.5 2000/03/23 23:17:56 fabian Exp $
+
+dnl
+dnl EGG_REMOVE_MOD(MODULE-NAME)
+dnl
+define(EGG_REMOVE_MOD,
+[${srcdir}/../../../misc/modconfig -q --top_srcdir=${srcdir}/../../.. --bindir=../../.. del $1])
+
+dnl
+dnl EGG_INIT(UNIQUE-SOURCE-FILE)
+dnl
+define(EGG_INIT,
+[AC_INIT($1)
+## SPLIT
+# configure  --  Special configure variant for eggdrop modules based on the
+#                GNU autoconf scripts.
+#
+# Automatically created by src/mod/eggautoconf from `configure.in'
+#
+
+echo "running in eggdrop mode."
+# This tells the code in eggmod.sh to search for the file `$1'.
+# That way we can make sure we're started from the correct directory.
+ac_egg_uniquefile=$1
+
+# Scan for out source directory
+ac_egg_srcdir=.
+for i in [$]*; do
+  case "[$]{i}" in
+    --srcdir=*)
+      ac_egg_srcdir=`echo [$]{i} | sed -e 's/^--srcdir=//'`
+    ;;
+  esac
+done
+if test -r [$]{ac_egg_srcdir}/../eggmod.sh; then
+	. [$]{ac_egg_srcdir}/../eggmod.sh
+else
+	echo "[$]0: error: failed to locate eggmod.sh in [$]{ac_egg_srcdir}/.." >&2
+	exit 1
+fi
+
+# Standard autoconf commands/tests follow below.])

+ 532 - 0
src/mod/eggmod.sh

@@ -0,0 +1,532 @@
+# This is the original `configure' script modified for eggdrop use. All
+# changes are marked with `EGG-CHANGE-POINT'.
+#
+# $Id: eggmod.sh,v 1.1 2000/02/25 21:51:30 fabian Exp $
+#
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+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=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -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 ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$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" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$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)
+    # 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 << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --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
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$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" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    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)
+    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" ;;
+
+  -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 ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=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" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+## EGG-CHANGE-POINT
+## Instead of a static filename, the variable $ac_egg_uniquefile specifies
+## the unique file.
+ac_unique_file=${ac_egg_uniquefile}
+
+# 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 its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  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
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+## EGG-CHANGE-POINT
+## The original configure script would now normally execute the
+## normal tests.

+ 28 - 16
src/mod/irc.mod/Makefile

@@ -1,35 +1,47 @@
 # Makefile for src/mod/irc.mod/
-# $Id: Makefile,v 1.10 1999/12/15 02:32:59 guppy Exp $
+# $Id: Makefile,v 1.11 2000/09/12 15:26:53 fabian Exp $
+
+srcdir = .
+
 
 doofus:
 	@echo ""
 	@echo "Let's try this from the right directory..."
 	@echo ""
-	@cd ../../../; make
+	@cd ../../../ && make
 
 static: ../irc.o
 
-modules: ../../../irc.so
+modules: ../../../irc.$(MOD_EXT)
 
 ../irc.o:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c irc.c
-	rm -f ../irc.o
+	$(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c $(srcdir)/irc.c
+	@rm -f ../irc.o
 	mv irc.o ../
 
-../../../irc.so: ../irc.o
-	$(LD) -o ../../../irc.so ../irc.o
-	$(STRIP) ../../../irc.so
+../../../irc.$(MOD_EXT): ../irc.o
+	$(LD) -o ../../../irc.$(MOD_EXT) ../irc.o $(XLIBS)
+	$(STRIP) ../../../irc.$(MOD_EXT)
 
 depend:
-	$(CC) $(CFLAGS) $(CPPFLAGS) -MM *.c > .depend
+	$(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/irc.c > .depend
 
 clean:
-	@rm -f .depend *.o *.so *~
+	@rm -f .depend *.o *.$(MOD_EXT) *~
+distclean: clean
 
 #safety hash
-../irc.o: irc.c ../module.h ../../../config.h ../../main.h ../../lang.h \
- ../../eggdrop.h ../../flags.h ../../proto.h ../../../lush.h \
- ../../cmdt.h ../../tclegg.h ../../tclhash.h ../../chan.h \
- ../../users.h ../modvals.h ../../tandem.h irc.h \
- ../server.mod/server.h ../channels.mod/channels.h chan.c mode.c \
- cmdsirc.c msgcmds.c tclirc.c
+../irc.o: .././irc.mod/irc.c ../../../src/mod/module.h \
+ ../../../src/main.h ../../../config.h ../../../src/lang.h \
+ ../../../src/eggdrop.h ../../../src/flags.h ../../../src/proto.h \
+ ../../../lush.h ../../../src/misc_file.h ../../../src/cmdt.h \
+ ../../../src/tclegg.h ../../../src/tclhash.h ../../../src/chan.h \
+ ../../../src/users.h ../../../src/compat/compat.h \
+ ../../../src/compat/inet_aton.h ../../../src/compat/snprintf.h \
+ ../../../src/compat/memset.h ../../../src/compat/memcpy.h \
+ ../../../src/compat/strcasecmp.h ../../../src/compat/strftime.h \
+ ../../../src/mod/modvals.h ../../../src/tandem.h ../irc.mod/irc.h \
+ ../../../src/mod/server.mod/server.h \
+ ../../../src/mod/channels.mod/channels.h ../irc.mod/chan.c \
+ ../irc.mod/mode.c ../irc.mod/cmdsirc.c ../irc.mod/msgcmds.c \
+ ../irc.mod/tclirc.c

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 477 - 328
src/mod/irc.mod/chan.c


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 472 - 301
src/mod/irc.mod/cmdsirc.c


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است